對象恋技、消息、運(yùn)行期--10:runtime關(guān)聯(lián)對象

關(guān)聯(lián)對象

  • 給某個object關(guān)聯(lián)一個或多個其他對象逻族,這些對象通過“鍵”來區(qū)分蜻底,我們可以通過這個鍵給這個object綁定一個對象,也可以通過鍵獲取objct綁定對象聘鳞。object身上的一個鍵就對應(yīng)一個關(guān)聯(lián)對象薄辅,所以我們可以給object關(guān)聯(lián)多個對象要拂。類似字典,把關(guān)聯(lián)到object的值理解為字典中的value站楚,這些value通過key來存取脱惰。

  • 設(shè)置關(guān)聯(lián)對象時用的鍵是個“不透明指針”,在設(shè)置關(guān)聯(lián)對象時窿春,若想讓倆個鍵匹配到同一個值拉一,則二者必須是完全相同的指針才行。鑒于此谁尸,存取關(guān)聯(lián)對象用的key通常是一個靜態(tài)全局變量舅踪。

  • runtime提供了給我們3個API以管理關(guān)聯(lián)對象(存儲纽甘、獲取良蛮、移除):
    • objc_setAssociatedObject(object,key,value, objc_AssociationPolicy policy)

    • id objc_getAssociatedObject(object, key)

    • objc_removeAssociatedObjects(id object)
      參數(shù):
      object:被關(guān)聯(lián)的對象
      key:關(guān)聯(lián)的key,要求唯一
      value:關(guān)聯(lián)的對象
      objc_AssociationPolicy policy:內(nèi)存管理的策略

      注: objc_removeAssociatedObjects(id object)函數(shù)移除的是某個對象身上的所有關(guān)聯(lián)的對象悍赢。objc沒有給我們提供移除object身上單個關(guān)聯(lián)對象的函數(shù)决瞳,所以,一般通過objc_setAssociatedObject函數(shù)傳入nil來達(dá)到移除某個關(guān)聯(lián)對象的目的左权。

      內(nèi)存管理的策略

關(guān)聯(lián)類型 等效的@property
OBJC_ASSOCIATION_ASSIGN assign
OBJC_ASSOCIATION_RETAIN_NONATOMIC nonatomic,retain
OBJC_ASSOCIATION_COPY_NONATOMIC nonatomic,copy
OBJC_ASSOCIATION_RETAIN retain
OBJC_ASSOCIATION_COPY copy

給category的property添加getter和setter

在category中的使用 @property添加屬性 皮胡,不會生成帶下劃線的成員變量,也不會有setter和getter方法實現(xiàn)赏迟,所以我們通過runtime關(guān)聯(lián)對象的技術(shù)為已經(jīng)存在的類添加“屬性”屡贺,這樣我們只是實現(xiàn)了setter和getter方法,依然不會有帶下劃線的成員變量

#import "Phone.h"
@interface Phone (Info)
@property (nonatomic,copy) NSString *name;
@end

#import "Phone+Info.h"
#import <objc/runtime.h>
//定義常量 必須是C語言字符串
static const char *key = "name";
@implementation Phone (Info)
- (void)setName:(NSString *)name{
    objc_setAssociatedObject(self, key, name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)name{
    return objc_getAssociatedObject(self, key);
}
@end


#import "ViewController.h"
#import "Phone.h"
#import "Phone+Info.h"
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    Phone *phone = [[Phone alloc]init];
    phone.name = @"I'm iphone";
    NSLog(@"%@",phone.name);
}
@end

log:I'm iphone

給UIButton的category的添加回調(diào)方法

#import <UIKit/UIKit.h>
typedef void(^ButtonClickCallBack) (UIButton *button);
@interface UIButton (Base)
- (void)handleClickCallBack:(ButtonClickCallBack)callBack;
@end

#import "UIButton+Base.h"
#import <objc/runtime.h>
static const char *key = "Click";
@implementation UIButton (Base)
- (void)handleClickCallBack:(ButtonClickCallBack)callBack{

    objc_setAssociatedObject(self, key, callBack, OBJC_ASSOCIATION_COPY_NONATOMIC);
    [self addTarget:self action:@selector(buttonClicked) forControlEvents:UIControlEventTouchUpInside];
}

- (void)buttonClicked{
    ButtonClickCallBack callBack = objc_getAssociatedObject(self, key);
    if (callBack) {
        callBack(self);
    }
}
@end

#import "ViewController.h"
#import "UIButton+Base.h"
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIButton *button = [UIButton buttonWithType:UIButtonTypeContactAdd];
    [button setFrame:CGRectMake(100, 100, 100, 100)];
    [button handleClickCallBack:^(UIButton *button) {
        NSLog(@"button clicked");
    }];
    [self.view addSubview:button];
 }
@end

log: button clicked

參考

Effective+Objective-C 2.0 編寫高質(zhì)量iOS與OS X代碼的52個有效方法

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末锌杀,一起剝皮案震驚了整個濱河市甩栈,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌糕再,老刑警劉巖量没,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異突想,居然都是意外死亡殴蹄,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進(jìn)店門猾担,熙熙樓的掌柜王于貴愁眉苦臉地迎上來袭灯,“玉大人,你說我怎么就攤上這事稽荧。” “怎么了圾叼?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵蛤克,是天一觀的道長捺癞。 經(jīng)常有香客問我,道長矾飞,這世上最難降的妖魔是什么豹绪? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上濒翻,老公的妹妹穿的比我還像新娘屁柏。我一直安慰自己,他們只是感情好有送,可當(dāng)我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布淌喻。 她就那樣靜靜地躺著,像睡著了一般娶眷。 火紅的嫁衣襯著肌膚如雪似嗤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天届宠,我揣著相機(jī)與錄音烁落,去河邊找鬼。 笑死豌注,一個胖子當(dāng)著我的面吹牛伤塌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播轧铁,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼每聪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起药薯,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤绑洛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后童本,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體真屯,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年穷娱,在試婚紗的時候發(fā)現(xiàn)自己被綠了绑蔫。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡泵额,死狀恐怖配深,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情嫁盲,我是刑警寧澤篓叶,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站亡资,受9級特大地震影響澜共,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜锥腻,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望母谎。 院中可真熱鬧瘦黑,春花似錦、人聲如沸奇唤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽咬扇。三九已至甲葬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間懈贺,已是汗流浹背经窖。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留梭灿,地道東北人画侣。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像堡妒,于是被迫代替她去往敵國和親配乱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內(nèi)容