在沒有接觸runtime之前,我們接觸到的能給類進行擴展的方法有類目(category)和延展(extension)兩種。類目(category)可以給系統已有類添加擴展方法但是不能添加屬性,並且被添加的方法可以被此類的子類所繼承;延展(extension)為我們的自定義類添加屬性和方法,但是添加的屬性和方法都是私有的,在此類的子類中是無法訪問的。那么問題來了,如果我們想給系統已有類添加一些方便我們使用的屬性要怎么辦呢?上述這兩種方法中能給系統已有類添加的東西的就只有類目(category)了。
如何利用runtime給系統已有類添加屬性?下面用NSDictionary來舉例
首先我們給NSDictionary創建一個類目,並在.h文件中添加一個屬性
#import <Foundation/Foundation.h> @interface NSDictionary (MyDic) @property (nonatomic, copy) NSString *name; @end
一般情況下我們在類目(category)中添加屬性在外面使用的時候就是報錯
為了不報錯需要我們在.m文件中實現name屬性的setter、getter方法
- (void)setName:(NSString *)name { /** * 為某個類關聯某個對象 * * @param object#> 要關聯的對象 description#> * @param key#> 要關聯的屬性key description#> * @param value#> 你要關聯的屬性 description#> * @param policy#> 添加的成員變量的修飾符 description#> */ objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC); } - (NSString *)name { /** * 獲取到某個類的某個關聯對象 * * @param object#> 關聯的對象 description#> * @param key#> 屬性的key值 description#> */ return objc_getAssociatedObject(self, @selector(name)); }
實現了name屬性的setter和getter方法之后我們就把新添加的name屬性和NSDictionary類關聯起來了,現在在外面使用name屬性就不會報錯了!