1.基礎數(shù)據(jù)類型
Ivar
是表示實例變量的類型,其實際是一個指向objc_ivar
結構體的指針飒炎,其定義如下:
typedef struct objc_ivar *Ivar;
struct objc_ivar {
char *ivar_name OBJC2_UNAVAILABLE; // 變量名
char *ivar_type OBJC2_UNAVAILABLE; // 變量類型
int ivar_offset OBJC2_UNAVAILABLE; // 基地址偏移字節(jié)
#ifdef __LP64__
int space OBJC2_UNAVAILABLE;
#endif
}
objc_property_t
objc_property_t是表示Objective-C聲明的屬性的類型,其實際是指向objc_property結構體的指針郎汪,其定義如下:
typedefstruct objc_property *objc_property_t;
objc_property_attribute_t
objc_property_attribute_t定義了屬性的特性(attribute)闯狱,它是一個結構體,定義如下:
typedef struct {
const char *name; // 特性名
const char *value; // 特性值
} objc_property_attribute_t;
2.關聯(lián)對象(Associated Object)
關聯(lián)對象可以用在分類添加成員變量扩氢,我們可以把關聯(lián)對象想象成一個Objective-C對象(如字典)耕驰,這個對象通過給定的key連接到類的一個實例上。不過由于使用的是C接口朦肘,所以key是一個void指針(const void *)。我們還需要指定一個內存管理策略
OBJC_ASSOCIATION_ASSIGN
OBJC_ASSOCIATION_RETAIN_NONATOMIC
OBJC_ASSOCIATION_COPY_NONATOMIC
OBJC_ASSOCIATION_RETAIN
OBJC_ASSOCIATION_COPY
當宿主對象被釋放時媒抠,會根據(jù)指定的內存管理策略來處理關聯(lián)對象。如果指定的策略是assign趴生,則宿主釋放時,關聯(lián)對象不會被釋放苍匆;而如果指定的是retain或者是copy,則宿主釋放時浸踩,關聯(lián)對象會被釋放叔汁。我們甚至可以選擇是否是自retain/copy检碗。當我們需要在多個線程中處理訪問關聯(lián)對象的多線程代碼時,這就非常有用了折剃。
static char myKey;
objc_setAssociatedObject(self, &myKey, anObject, OBJC_ASSOCIATION_RETAIN);
在這種情況下,self對象將獲取一個新的關聯(lián)的對象anObject怕犁,且內存管理策略是自動retain關聯(lián)對象,當self對象釋放時因苹,會自動release關聯(lián)對象。另外扶檐,如果我們使用同一個key來關聯(lián)另外一個對象時凶杖,也會自動釋放之前關聯(lián)的對象款筑,這種情況下腾么,先前的關聯(lián)對象會被妥善地處理掉,并且新的對象會使用它的內存解虱。
id anObject = objc_getAssociatedObject(self, &myKey);
我們可以使用objc_removeAssociatedObjects函數(shù)來移除一個關聯(lián)對象,或者使用objc_setAssociatedObject函數(shù)將key指定的關聯(lián)對象設置為nil殴泰。
關聯(lián)對象操作函數(shù)包括以下:
// 設置關聯(lián)對象
void objc_setAssociatedObject ( id object, const void *key, id value, objc_AssociationPolicy policy );
// 獲取關聯(lián)對象
id objc_getAssociatedObject ( id object, const void *key );
// 移除關聯(lián)對象
void objc_removeAssociatedObjects ( id object );