1. 程式人生 > >關於執行時的方法使用:objc_setAssociatedObject

關於執行時的方法使用:objc_setAssociatedObject

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSString * overview = @"overview";
    self.model= [[DataModel alloc] init];
    [self.model setValue:@"searph" forKey:@"stockName"];
    [self.model setValue:@"10.0" forKey:@"price"];
    [self.model addObserver:self forKeyPath:@"price" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];
    <span style="color:#ff0000;">objc_setAssociatedObject</span>(self.model, &overviewKey, overview, OBJC_ASSOCIATION_RETAIN);
}
-(IBAction)btnpressed:(id)sender
{
    [self.model setValue:@"20.0" forKey:@"price"];
}
<pre name="code" class="objc">-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if([keyPath isEqualToString:@"price"]){
        NSLog(@"changeDic = %@",change);
        NSString * associatedObject = (NSString *)<span style="color:#ff0000;">objc_getAssociatedObject</span>(self.model, &overviewKey);
        NSLog(@"associatedObject >>>>>>> %@",associatedObject);
    }
}
2014-09-22 23:01:25.470 TestAssociatedObject[61080:60b] changeDic = {
    kind = 1;
    new = 20;
    old = 10;
}
2014-09-22 23:01:25.471 TestAssociatedObject[61080:60b] associatedObject >>>>>>> overview
大致流程:註冊model的觀察者,點選button改變某屬性,從而觸發相應的回撥,列印相關資訊。

建立關聯:

建立關聯要使用到Objective-C的執行時函式:objc_setAssociatedObject來把一個物件與另外一個物件進行關聯。

<span style="color:#ff0000;">objc_setAssociatedObject</span>(self.model, &overviewKey, overview, OBJC_ASSOCIATION_RETAIN);
此方法的四個引數分別為:源物件、關鍵字、關聯的物件、關聯策略。
關鍵字是一個void型別的指標,每個關聯的關鍵字必須是唯一的,通常用靜態變數作為關鍵字。

關聯策略表明了相關的物件是通過賦值,保留引用還是複製的方式進行關聯的;

獲取相關聯的物件:

NSString * associatedObject = (NSString *)<span style="color:#ff0000;">objc_getAssociatedObject</span>(self.model, &overviewKey);
引數分別為:源物件、關鍵字

斷開關聯:

 斷開關聯是使用objc_setAssociatedObject函式,傳入nil值即可

<span style="color: rgb(255, 0, 0);">objc_setAssociatedObject</span>(self.model, &overviewKey, nil, OBJC_ASSOCIATION_RETAIN);
使用函式objc_removeAssociatedObjects可以斷開所有關聯。通常情況下不建議使用這個函式,因為他會斷開所有關聯。只有在需要把物件恢復到“原始狀態”的時候才會使用這個函式。