Objective-C——關聯對象

來源:互聯網
上載者:User

標籤:

動態語言

OC是一種動態語言,它的方法,對象的類型都是到啟動並執行時候才能夠確定的。所以這就使得OC存在了關聯對象這一強大的機制。

 

關聯對象

所謂關聯對象,其實就是我們在運行時對一個已存在的對象上面綁定一個對象,使兩個對象變成動態彙總關係。

關聯對象和屬性一樣有著關鍵字,以下是關聯對象的儲存策略:

關聯類別型 等效的@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

 

 

 

 

 

 

關聯對象主要靠下面三個函數,它們都位於<objc/runtime>下

void objc_setAssociatedObject(id object, void *key ,id value ,objc_AssociationPolicy policy)

設定關聯對象

參數 說明
object 要進行關聯的對象
key 一個記憶體表示,在比較兩個關聯對象是否相等時,比較大的就是記憶體位址,所以一般用一個全域靜態變數表示
value 被關聯的對象
policy 儲存策略

 

 

 

 

 

id objc_getAssociatedObject(id object, void *key)

擷取關聯對象

void objc_removeAssociatedObjects(id object)

刪除關聯對象

 

作用

關聯對象一般用於動態擴充一個對象,但是這一般都是在其他方法不行的事後才會使用,因為關聯對象很可能會出現難以尋找的bug。

關聯對象有時也會用於在category向類添加屬性,這點等會兒在分析。

下面Demo在UIAlertView上面動態綁定了一個block,把按鈕處理邏輯和alert調用整合在了一起。

static char *AlertKey = "alertKey";- (void)viewDidLoad {    [super viewDidLoad];       alert = [[UIAlertView alloc] initWithTitle:@"alert" message:@"message" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"other", nil];    alert.delegate = self;}- (IBAction)click:(id)sender {        void (^block) (NSInteger) = ^(NSInteger buttonIndex){        if (buttonIndex == 0){            NSLog(@"click cancel");        }        else{            NSLog(@"click other");        }    };    objc_setAssociatedObject(alert, AlertKey, block, OBJC_ASSOCIATION_COPY);    [alert show];}- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{    void (^block)(NSInteger) = objc_getAssociatedObject(alertView, AlertKey);    block(buttonIndex);}

運行程式點擊兩個按鈕分別輸出如下

2015-08-11 22:51:27.146 Dynamic[4592:2833778] click other2015-08-11 22:51:28.262 Dynamic[4592:2833778] click cancel

 

接下來我們給UIViewController在category中添加一個addition屬性

#import "ViewController.h"#import <objc/runtime.h>@interface UIViewController (Addition)@property(nonatomic ,copy) NSString *addition;@end
#import "UIViewController+Addition.h"static const void *IndieBandNameKey = &IndieBandNameKey;@implementation UIViewController (Addition)-(void)setAddition:(NSString *)addition{    objc_setAssociatedObject(self, IndieBandNameKey, addition, OBJC_ASSOCIATION_COPY);}-(NSString *)addition{    return objc_getAssociatedObject(self, IndieBandNameKey);}@end

這裡說明一下,這裡關聯的實際上是形參addition,和屬性沒有什麼關係,寫@property 就是為了能夠使用‘.’文法。但是@porperty裡面的屬性儲存區策略還是要和關聯對象一致的,這樣不容易造成誤解。

所以每次setAddition實際上我們並不是修改了原有記憶體的值,而是改變了指標指向的地址,這裡需要注意一下。

然後修改剛才alert的代碼

- (void)viewDidLoad {    [super viewDidLoad];       alert = [[UIAlertView alloc] initWithTitle:@"alert" message:@"message" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"other", nil];    alert.delegate = self;    self.addition = @"addition";    }- (IBAction)click:(id)sender {        void (^block) (NSInteger) = ^(NSInteger buttonIndex){        if (buttonIndex == 0){            NSLog(@"click cancel");            objc_removeAssociatedObjects(self);        }        else{            NSLog(@"click other");            NSLog(@"%@",self.addition);        }    };    objc_setAssociatedObject(alert, AlertKey, block, OBJC_ASSOCIATION_COPY);    [alert show];}- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{    void (^block)(NSInteger) = objc_getAssociatedObject(alertView, AlertKey);    block(buttonIndex);}

注意三條加粗的語句,然後我們運行看結果

2015-08-11 22:53:54.353 Dynamic[4655:2849502] click other2015-08-11 22:53:54.353 Dynamic[4655:2849502] addition2015-08-11 22:53:55.804 Dynamic[4655:2849502] click cancel2015-08-11 22:53:57.491 Dynamic[4655:2849502] click other2015-08-11 22:53:57.491 Dynamic[4655:2849502] (null)

首先我們使用了關聯對象,所以點擊other的時候會看到列印出了addition。點擊cancel的時候又因為我們remove了關聯對象,此時再點擊other的時候addition就變成null了。

Objective-C——關聯對象

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.