最近在看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ò)張成員變量)。