在ios開發中,有時候會遇到以下的問題,需要在一個類中新增自己的一些屬性和方法。一般的做法是重寫一個類來繼承它,但是有時候就只是需要新增一些簡單的屬性和方法,那麼這樣做就顯得過於麻煩,其實在IOS中還有更簡單的方法,那就是Category。
用一個例子來簡單介紹以下Category的用法。
@interface UIImageView (CategoryName)
只需要在interface中加上category的名稱。
新增自定義的方法(Category)
我們來給UIImageView新增一個自定義的speak
方法
1 2 3 4 5 |
@interface UIImageView (image) - (void)speak:(NSString *)words; @end |
接下來就是對這個方法的實現
1 2 3 4 5 6 7 |
@implementation UIImageView (image) - (void)speak:(NSString *)words { NSLog(@"%@",words); } @end |
一旦實現了該方法,那麼就可以在UIImageView中直接呼叫speak
方法
新增自定義的屬性(associative)
新增自定義屬性需要用到associative
1 2 3 4 5 |
@interface UIImageView (title) @property (nonatomic, strong) NSString *title; @end |
但是僅僅這樣是沒有辦法使用的,還需要匯入包#import <objc/runtime.h>
用到了oc的執行時
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@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是在執行時動態的新增屬性,一般用的比較少。但是還是需要熟悉一下。