iOS runtime 關(guān)聯(lián)對(duì)象

最近在看runtime的相關(guān)知識(shí),感覺(jué)里面東西還蠻多的,反正感覺(jué)runtime被戴上了很多高大上的帽子。查看了很多文章,下面兩個(gè)頭文件是被提及的最多的,上面一個(gè)頭文件主要提及到OC中的類(lèi)、方法、屬性和成員變量,詳細(xì)的說(shuō)明了他們的本質(zhì),而下面的頭文件說(shuō)明了OC中方法調(diào)用的本質(zhì),同時(shí)這些頭文件中涉及到很多C語(yǔ)言中的概念,主要是結(jié)構(gòu)體,結(jié)構(gòu)體指針等,看著有點(diǎn)暈乎。

#import <objc/runtime.h>
#import <objc/message.h>

但是我寫(xiě)這篇文章的主要意圖是為了給runtime的關(guān)聯(lián)對(duì)象做一個(gè)總結(jié),當(dāng)然現(xiàn)在也只是初步了解,后期有新的看法就會(huì)更新這篇文章的。

1.關(guān)聯(lián)對(duì)象的概念

關(guān)聯(lián)對(duì)象說(shuō)的簡(jiǎn)單點(diǎn)就是利用鍵值對(duì)的方式把兩個(gè)對(duì)象關(guān)聯(lián)起來(lái),而關(guān)聯(lián)的唯一標(biāo)示就是key值

2.關(guān)聯(lián)對(duì)象常用的方法
    /**
     *  @author liyong
     *
     *  為object添加關(guān)聯(lián)對(duì)象value
     *
     *  @param object 關(guān)聯(lián)對(duì)象中的被關(guān)聯(lián)的對(duì)象
     *  @param key    關(guān)聯(lián)的key值(這個(gè)key值必須保證是一個(gè)對(duì)象級(jí)別的唯一常量??這地方有待研究,一個(gè)key值不知道為啥這么復(fù)雜)
     *  @param value  關(guān)聯(lián)的對(duì)象
     *  @param policy 關(guān)聯(lián)的內(nèi)存管理策略
     *
     *  @return
     */
    objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
  • 關(guān)聯(lián)的key值有三種推薦值
    1.聲明 static char kAssociatedObjectKey; ,使用 &kAssociatedObjectKey 作為 key 值
    2.聲明 static void *kAssociatedObjectKey = &kAssociatedObjectKey; ,使用 kAssociatedObjectKey 作為 key 值
    3.用 selector ,使用 getter 方法的名稱(chēng)作為 key 值(這種方法用的比較多)

  • policy是關(guān)聯(lián)的對(duì)象的內(nèi)存管理策略,是一個(gè)枚舉類(lèi)型,值有如下五種,使用方法跟屬性的描述一樣

OBJC_ASSOCIATION_ASSIGN             // 對(duì)關(guān)聯(lián)對(duì)象進(jìn)行弱引用
OBJC_ASSOCIATION_RETAIN_NONATOMIC   // 對(duì)關(guān)聯(lián)對(duì)象進(jìn)行強(qiáng)引用(非原子)
OBJC_ASSOCIATION_COPY_NONATOMIC     // 對(duì)關(guān)聯(lián)對(duì)象進(jìn)行拷貝引用(非原子)
OBJC_ASSOCIATION_RETAIN             // 對(duì)關(guān)聯(lián)對(duì)象進(jìn)行強(qiáng)引用
OBJC_ASSOCIATION_COPY               // 對(duì)關(guān)聯(lián)對(duì)象進(jìn)行拷貝引用
    /**
     *  @author liyong
     *
     *  根據(jù)被關(guān)聯(lián)的對(duì)象和關(guān)聯(lián)的key值獲取關(guān)聯(lián)的對(duì)象
     *
     *  @param object 關(guān)聯(lián)對(duì)象中的被關(guān)聯(lián)的對(duì)象
     *  @param key    關(guān)聯(lián)的key值
     *
     *  @return 關(guān)聯(lián)的對(duì)象
     */
    objc_getAssociatedObject(id object, const void *key)
    /**
     *  @author liyong
     *
     *  移除被關(guān)聯(lián)對(duì)象的所有關(guān)聯(lián)對(duì)象
     *  但是這個(gè)方法用的不多,把objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
     *  中的value設(shè)為nil就會(huì)根據(jù)key清空object關(guān)聯(lián)的對(duì)象
     */
    objc_removeAssociatedObjects(id object)

大家要是覺(jué)得注釋的不是很好的話(huà),<objc/runtime.h>中有詳細(xì)的英文注釋。

3.關(guān)聯(lián)對(duì)象的用法

關(guān)聯(lián)對(duì)象用的最多的就是為已有的類(lèi)添加屬性(關(guān)于屬性和實(shí)例變量的區(qū)別可以查看屬性與實(shí)例變量),至于別的用法我暫時(shí)還沒(méi)遇到????(我感覺(jué)runtime在開(kāi)發(fā)中用的本來(lái)就少,但是對(duì)runtime的學(xué)習(xí)有助于對(duì)OC和iOS開(kāi)發(fā)的深入了解)。
話(huà)不多說(shuō),直接上代碼

@interface LYPersonModel (testCategory)

@property (copy, nonatomic) NSString *englishName;

@end
@implementation LYPersonModel (testCategory)

- (void)setEnglishName:(NSString *)englishName
{
    objc_setAssociatedObject(self, @selector(englishName), englishName, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)englishName
{
    return objc_getAssociatedObject(self, @selector(englishName));
}

@end

代碼不多,就兩句,利用class_copyPropertyList()獲取對(duì)象的成員變量就會(huì)發(fā)現(xiàn)類(lèi)別中的屬性也會(huì)出現(xiàn)列表中(但是利用class_copyIvarList()獲取成員變量列表的時(shí)候發(fā)現(xiàn)沒(méi)有待下劃線(xiàn)的成員變量,看來(lái)關(guān)聯(lián)對(duì)象只是變相的為類(lèi)擴(kuò)展了屬性,實(shí)際上并沒(méi)有擴(kuò)張成員變量)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容