關聯(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
框架
使用關聯,咱們能夠不用修改類的定義而爲其對象增長存儲空間。這在咱們沒法訪問到類的源碼的時候或者是考慮到二進制兼容性的時候是很是有用。
關聯是基於關鍵字的,所以,咱們能夠爲任何對象增長任意多的關聯,每一個都使用不一樣的關鍵字便可。關聯是能夠保證被關聯的對象在關聯對象的整個生命週期都是可用的(在垃圾自動回收環境下也不會致使資源不可回收)。函數
建立關聯要使用到Objective-C的運行時函數:objc_setAssociatedObject來把一個對象與另一個對象進行關聯。該函數須要四個參數:源對象,關鍵字,關聯的對象和一個關聯策略。固然,此處的關鍵字和關聯策略是須要進一步討論的。
■ 關鍵字是一個void類型的指針。每個關聯的關鍵字必須是惟一的。一般都是會採用靜態變量來做爲關鍵字。
■ 關聯策略代表了相關的對象是經過賦值,保留引用仍是複製的方式進行關聯的;還有這種關聯是原子的仍是非原子的。這裏的關聯策略和聲明屬性時的很相似。這種關聯策略是經過使用預先定義好的常量來表示的。atom
//
// UIView+AddProperty.h
// category添加屬性
//
// Created by jie on 15/4/13.
// Copyright (c) 2015年 jie. All rights reserved.
//spa
@interface UIView (AddProperty)
@property(nonatomic,copy)NSString *title;
@end .net
//
// UIView+AddProperty.m
// category添加屬性
//
// Created by jie on 15/4/13.
// Copyright (c) 2015年 jie. All rights reserved.
//指針
@implementation UIView (AddProperty)
static void MyKey = (void )@"MyKey";對象
-(NSString *)title
{
return objc_getAssociatedObject(self, MyKey);
}繼承
-(void)setTitle:(NSString *)title
{
objc_setAssociatedObject(self, MyKey, title, OBJC_ASSOCIATION_COPY);
}
@end生命週期
//
// ViewController.m
// category添加屬性
//
// Created by jie on 15/4/13.
// Copyright (c) 2015年 jie. All rights reserved.
//ci
@interface ViewController ()
@end
@implementation ViewController
(void)viewDidLoad {
[super viewDidLoad];
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(100, 150, 100, 100)];
view.backgroundColor = [UIColor redColor];
[self.view addSubview:view];
view.title = @"哈嘍 jie category 添加屬性";
NSLog(@"%@",view.title);
}
/**
在iOS開發中,有時候會遇到如下的問題,須要在一個類中添加本身的一些屬性和方法。
一、通常的作法是重寫一個類來繼承它,
二、可是有時候就只是須要添加一些簡單的屬性和方法,那麼這樣作就顯得過於麻煩,其實在iOS中還有更簡單的方法,那就是Category.
Category的侷限性 主要有兩方面侷限性: (1)沒法向類中添加新的實例變量,類別沒有位置容納實例變量。能夠經過associative來解決 (2)名稱衝突,即當類別中的方法與原始類方法名稱衝突時,類別具備更高的優先級。類別方法將徹底取代初始方法從而沒法再使用初始方法。這個相似於方法的重載,可是這裏是直接覆蓋了原方法 類別的做用 類別主要有3個做用: (1)能夠將類的實現分散到多個不一樣文件或多個不一樣框架中,方便代碼管理。也能夠對框架提供類的擴展(由於框架類沒有源碼,不能修改)。 (2)建立對私有方法的前向引用:若是其餘類中的方法未實現,在你訪問其餘類的私有方法時編譯器報錯這時使用類別,在類別中聲明這些方法(沒必要提供方法實現),編譯器就不會再產生警告 (3)向對象添加非正式協議:建立一個NSObject的類別稱爲「建立一個非正式協議」,由於能夠做爲任何類的委託對象使用。 associative associative是在運行時動態的添加屬性,通常用的比較少。可是仍是須要熟悉一下。 */@end