有時候咱們須要在現有的類存放一些額外的信息,一般的作法是繼承一個子類,而後定義新增長的屬性,然而若是咱們爲每一個須要的類都添加一個類顯得太麻煩了,objc提供了一個關聯屬性的特性,能夠給一個對象關聯一個屬性(作過.NET的朋友必定熟悉附加屬性,objc的關聯屬性與.NET的附加屬性有點相似相似)函數
使用關聯屬性很簡單,下面是幾個主要的函數atom
//設置關聯屬性
objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) //獲取關聯屬性
id result = objc_getAssociatedObject(id object, const void *key) //刪除全部附加屬性
objc_removeAssociatedObjects(id object)
咱們聲明屬性的時候會聲明:copy,retain,assign 內存管理方式,在設置關聯屬性的時候也有,即 objc_setAssociatedObject 的第四個參數spa
關聯類型 | 等效@property屬性 |
OBJC_ASSOCIATION_ASSIGN指針 |
assign |
OBJC_ASSOCIATION_RETAIN_NONATOMICcode |
nonatomic, retainorm |
OBJC_ASSOCIATION_COPY_NONATOMIC對象 |
nonatomic, copy |
OBJC_ASSOCIATION_RETAINblog |
retain |
OBJC_ASSOCIATION_COPY繼承 |
copy |
關聯屬性的附加至關於NSDictionary,經過鍵值對存儲,可是有一點跟NSDictionary不同的是,設置關聯對象所用的鍵(key)是不透明指針(opaque pointer),NSDictionary判斷兩個Key的isEqual方法判斷是否相等,而關聯對象只判斷兩個key的地址是否相等,而不會比較對象具體的值內存
看看下面例子
NSString *key1 = @"aaa"; NSString *key2 = [NSString stringWithFormat:@"aaa"]; NSString *key3 = @"bbb"; NSObject *obj = [[NSObject alloc] init]; objc_setAssociatedObject(obj, key1.UTF8String, @"aaa1", OBJC_ASSOCIATION_RETAIN_NONATOMIC); objc_setAssociatedObject(obj, key2.UTF8String, @"aaa2", OBJC_ASSOCIATION_RETAIN_NONATOMIC); objc_setAssociatedObject(obj, key3.UTF8String, @"bbb", OBJC_ASSOCIATION_RETAIN_NONATOMIC); id value1 = objc_getAssociatedObject(obj, key1.UTF8String); id value2 = objc_getAssociatedObject(obj, key2.UTF8String); id value3 = objc_getAssociatedObject(obj, key3.UTF8String); NSLog(@"value1 = %@", value1); NSLog(@"value2 = %@", value2); NSLog(@"value3 = %@", value3);
輸出
這裏的key1和key2都是@"aaa",可是取出來的value1和value2卻不同,這是由於key1和key2的地址不同,在匹配的時候關聯對象視爲不一樣的key,因此一般咱們在定義關聯對象的key的時候使用靜態全局變量做爲鍵,這樣能夠保證地址一致
static char *key = "aaa"; NSObject *obj = [[NSObject alloc] init]; objc_setAssociatedObject(obj, key, @"aaa1", OBJC_ASSOCIATION_RETAIN_NONATOMIC); objc_setAssociatedObject(obj, key, @"aaa2", OBJC_ASSOCIATION_RETAIN_NONATOMIC); id value1 = objc_getAssociatedObject(obj, key); //把原有的值覆蓋
id value2 = objc_getAssociatedObject(obj, key); NSLog(@"value1 = %@", value1); NSLog(@"value2 = %@", value2);
參考文章: