你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS中為什麼非要用runtime才能在分類中擴展屬性呢

iOS中為什麼非要用runtime才能在分類中擴展屬性呢

編輯:IOS開發綜合

想必大家都知道在分類中能擴展屬性,而對於能不能擴展屬性,能不能擴展成員變量是不是有點模糊,今天元宵節,我就清清嗓子說上兩句吧

論點

(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才能在分類中擴展屬性呢的全文介紹,希望對您學習和使用IOS應用開發有所幫助.

【iOS中為什麼非要用runtime才能在分類中擴展屬性呢】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved