開頭先說明一下纱耻,之所以把這二者放在一起比較,是因?yàn)榻裉炜吹搅艘粋€(gè)很有趣的寫法
- (void)setLk_imageInfo:(LKImageInfo *)imageInfo
{
objc_setAssociatedObject(self, @selector(setLk_imageInfo:), imageInfo, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
我們都知道茅坛,在OC中如果想給分類添加屬性@property
是不能直接生成對應(yīng)的setter
和getter
的而且即使手寫setter
和getter
也不能使用實(shí)例變量音半,所以只能通過runtime
中這種關(guān)聯(lián)的形式來綁定特定對象。
再來看一下objc_setAssociatedObject
的定義:
objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key,
id _Nullable value, objc_AssociationPolicy policy)
可以看到第二個(gè)參數(shù)key
需要一個(gè) const void *
類型的參數(shù)作為綁定的key,以往我在使用這個(gè)方法的時(shí)候都會自己生成一個(gè)key曹鸠,而今天看到的代碼中則使用了@selector(setLk_imageInfo:)
煌茬,傳入了一個(gè)SEL
,對此我也做了簡單的實(shí)驗(yàn)物延。
先來看一下SEL
的定義:
/// An opaque type that represents a method selector.
typedef struct objc_selector *SEL;
可以看到SEL
是一個(gè)結(jié)構(gòu)體指針宣旱,而 const void *
是一個(gè)無類型指針常量,所以從 SEL -> const void*
來賦值是說得通的叛薯,但是如果想反過來使用是不可以的浑吟。
const void *sel = @selector(beginTimer);
Obj *obj = [Obj new];
[obj performSelector:sel];
最開始對sel的賦值并不會有警告,因?yàn)関oid*本身就是無類型耗溜,但是這段代碼將無法執(zhí)行并且報(bào)錯组力。
最后,今天也算是學(xué)到了一個(gè)寫關(guān)聯(lián)的時(shí)候偷懶的好方法:D抖拴。