想必大家都知道在分類中能擴展屬性,而對於能不能擴展屬性,能不能擴展成員變量是不是有點模糊,今天元宵節,我就清清嗓子說上兩句吧
論點(1)分類中是能擴展屬性的
(2)分類是不能給一個類擴展成員變量的
強調一下,分類不是類,它只是對類的一個擴展,沒有ISA指針,我們知道我們可以通過runtime在不影響原來模塊的情況下給模塊擴展方法,有沒有感覺這一句話好像也可以描述分類,所以你可以認為分類是實現這一功能的捷徑,不然你覺得是用分類擴展方法容易還是用runtime來實現容易啊(正值年輕,說話有點沖~_~ !!)。
論據先說說屬性,屬性是對成員變量的一個封裝,當我們聲明一個屬性的時候,Xcode會給我們默認創建一個 _屬性名 的成員變量,也會給我們自動創建getter和setter方法。當然我們也可以用@synthesize指定其關聯的變量
例如給屬性name指定其關聯的變量@synthesize name = xxx;
self.name其實是操作的實例變量xxx,而不是_name了。
窩草,扯遠了,回歸正傳。。
所以我們要添加一個屬性得有三樣東西,setter、getter以及關聯的成員變量。
在分類中Xcode不會為我們自動創建setter、getter方法,但是我們可以手動實現,但是如何把一個變量關聯到屬性上呢,直接聲明一個全局變量不行嗎,事實證明不太行,對於getter方法還好說,直接返回一個變量就行,可是setter方法卻不行,因為你要找到該屬性關聯的變量你才能給人家賦值啊,怎麼辦?怎麼辦??這只能用runtime的對象關聯來實現了
.m文件中
// 定義關聯的key
static const char *key = "name";
@implementation NSObject (Property)
- (NSString *)name
{
// 根據關聯的key,獲取關聯的值。
return objc_getAssociatedObject(self, key);
}
- (void)setName:(NSString *)name
{
// 參數一:目標對象
// 參數二:關聯的key,可以通過這個key獲取
// 參數三:關聯的value
// 參數四:關聯的策略
objc_setAssociatedObject(self, key, name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
看到這裡你也許就會說,這TMD不是把變量給添加上去了嗎?我表示默默一笑,如果你打印IVarList你就會發現並沒有這個變量,只能打印出添加的屬性。
其實對象關聯只是關聯上去了,並沒有把變量添加進去,說了這麼多這回你該信了吧。
原因就是分類不是類,他沒有ISA指針,下面是ISA指針,可以看出他本質上是一個結構體(只是換了個馬甲被稱之為Class類型,怕你迷糊,再說明白一點,ISA指針就是Class類型),通過ISA指針才能找指向變量的ivars,也就是說你都不知道變量的家,你怎麼去給它生猴子啊,但是奇怪了,ISA指針裡沒有指向屬性數組的指針,沒有是對的,要不然這一段的解釋就廢了,可是講真,屬性指針在哪啊???有知道的小伙伴請告訴我一下 >_< !!!
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE;
const char *name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
struct objc_cache *cache OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */
結論
分類中可以給一個對象(類也是對象)添加屬性,但是不能添加成員變量,只能關聯上去。
注意:如果不信,你可以自己再打印一遍吧,會發現只能打印出添加的屬性,打印不出變量。
【iOS中為什麼非要用runtime才能在分類中擴展屬性呢】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!