在iOS開發中,有時候會遇到以下的問題,需要在一個類中添加自己的一些屬性和方法。一般的做法是重寫一個類來繼承它,但是有時候就只是需要添加一些簡單的屬性和方法,那麼這樣做就顯得過於麻煩,其實在iOS中還有更簡單的方法,那就是Category.
用一個例子來簡單介紹以下Category的用法。
@interface UIImageView (CategoryName)
只需要在interface中加上category的名稱。
添加自定義的方法(Category)
我們來給UIImageView添加一個自定義的 speak 方法
@interface UIImageView (image) - (void)speak:(NSString *)words; @end
接下來就是對這個方法的實現
@implementation UIImageView (image) - (void)speak:(NSString *)words { NSLog(@"%@",words); } @end
一旦實現了該方法,那麼就可以在UIImageView中直接調用 speak 方法
添加自定義的屬性(associative)
添加自定義屬性需要用到 associative
@interface UIImageView (title) @property (nonatomic, strong) NSString *title; @end
但是僅僅這樣是沒有辦法使用的,還需要導入包 #import
用到了OC的運行時
@implementation UIImageView (title) static void * MyKey = (void *)@"MyKey"; - (NSString *)title { return objc_getAssociatedObject(self, MyKey); } - (void) setTitle:(NSString *)title { objc_setAssociatedObject(self, MyKey, title, OBJC_ASSOCIATION_COPY_NONATOMIC); } @end
然後實現該屬性的get和set方法
Category的局限性
主要有兩方面局限性:
(1)無法向類中添加新的實例變量,類別沒有位置容納實例變量。可以通過associative來解決
(2)名稱沖突,即當類別中的方法與原始類方法名稱沖突時,類別具有更高的優先級。類別方法將完全取代初始方法從而無法再使用初始方法。這個類似於方法的重載,但是這裡是直接覆蓋了原方法
類別的作用
類別主要有3個作用:
(1)可以將類的實現分散到多個不同文件或多個不同框架中,方便代碼管理。也可以對框架提供類的擴展(因為框架類沒有源碼,不能修改)。
(2)創建對私有方法的前向引用:如果其他類中的方法未實現,在你訪問其他類的私有方法時編譯器報錯這時使用類別,在類別中聲明這些方法(不必提供方法實現),編譯器就不會再產生警告
(3)向對象添加非正式協議:創建一個NSObject的類別稱為“創建一個非正式協議”,因為可以作為任何類的委托對象使用。
associative
associative是在運行時動態的添加屬性,一般用的比較少。但是還是需要熟悉一下。