Objective-C Category

—Category—框架

首先咱們來談談Category。
 
因爲Objective-C不支持多重繼承,因此提供了一種不同凡響的方式——Category,能夠動態的爲已經存在的類添加新的行爲。這樣能夠保證類的原始設計規模較小,功能增長時再逐步擴展。使用Category對類進行擴展時,不須要訪問其源代碼,也不須要建立子類。Category使用簡單的方式,實現了類的相關方法的模塊化,把不一樣的類方法分配到不一樣的分類文件中。
 
實現起來很簡單,咱們舉例說明。
SomeClass.h
@interface SomeClass : NSObject{
}
-(void) print;
@end 
 
這是類SomeClass的聲明文件,其中包含一個實例方法print。若是咱們想在不修改原始類、不增長子類的狀況下,爲該類增長一個hello的方法,只須要簡單的定義兩個文件SomeClass+Hello.h和SomeClass+Hello.m,在聲明文件和實現文件中用「()」把Category的名稱括起來便可。聲明文件代碼以下:
 
#import "SomeClass.h"
 
@interface SomeClass (Hello)
-(void)hello;
@end
實現文件代碼以下
#import "SomeClass+Hello.h"
@implementationSomeClass (Hello)
-(void)hello{
    NSLog (@"name:%@ ", @"Jacky");
}
@end 
其中Hello是Category的名稱,若是你用XCode建立Category,那麼須要填寫的內容包括名稱和要擴展的類的名稱。這裏還有一個約定成俗的習慣,將聲明文件和實現文件名稱統一採用「原類名+Category」的方式命名。
調用也很是簡單,毫無壓力,以下:
首先引入Category的聲明文件,而後正常調用便可。
#import "SomeClass+Hello.h"
 
SomeClass * sc =[[SomeClass alloc] init];
[sc hello] 
執行結果是:
name Jacky 
 
Category的使用場景:
一、當你在定義類的時候,在某些狀況下(例如需求變動),你可能想要爲其中的某個或幾個類中添加方法。
二、一個類中包含了許多不一樣的方法須要實現,而這些方法須要不一樣團隊的成員實現
三、當你在使用基礎類庫中的類時,你可能但願這些類實現一些你須要的方法。
 
遇到以上這些需求,Category能夠幫助你解決問題。固然,使用Category也有些問題須要注意,
一、Category能夠訪問原始類的實例變量,但不能添加變量,若是想添加變量,能夠考慮經過繼承建立子類。
二、Category能夠重載原始類的方法,但不推薦這麼作,這麼作的後果是你不再能訪問原來的方法。若是確實要重載,正確的選擇是建立子類。
三、和普通接口有所區別的是,在分類的實現文件中能夠沒必要實現全部聲明的方法,只要你不去調用它。
 
用好Category能夠充分利用Objective-C的動態特性,編寫出靈活簡潔的代碼。
 
—Protocol— 
下面咱們再來看Protocol。
Protocol,簡單來講就是一系列不屬於任何類的方法列表,其中聲明的方法能夠被任何類實現。這種模式通常稱爲代理(delegation)模式。你經過Protocol定義各類行爲,在不一樣的場景採用不一樣的實現方式。在iOS和OS X開發中,Apple採用了大量的代理模式來實現MVC中View和Controller的解耦。
 
定義Protocol很簡單,在聲明文件(h文件)中經過關鍵字@protocol定義,而後給出Protocol的名稱,方法列表,而後用@end表示Protocol結束。在@end指令結束以前定義的方法,都屬於這個Protocol。例如:
複製代碼
@protocol ProcessDataDelegate <NSObject>
@required
- (void) processSuccessful: (BOOL)success;

@optional
- (id) submitOrder: (NSNumber *) orderid;
@end
複製代碼
 
以上代碼能夠單獨放在一個h文件中,也能夠寫在相關類的h文件中,能夠視具體狀況而定。該Protocol包含兩個方法,processSuccessful和submitOrder。這裏還有兩個關鍵字,@required和@optional,表示若是要實現這個協議,那麼processSuccessful方法是必需要實現的,submitOrder則是可選的,這兩個註解關鍵字是在Objective-C 2.0以後加入的語法特性。若是不註明,那麼方法默認是@required的,必須實現。
 
那麼如何實現這個Protocol呢,很簡單,建立一個普通的Objective-C類,取名爲TestAppDelegate,這時會生成一個h文件和m文件。在h文件中引入包含Protocol的h文件,以後聲明採用這個Protocol便可,以下:
@interface TestAppDelegate : NSObject<ProcessDataDelegate>;

@end
用尖括號(<...>)括起來的ProcessDataDelegate就是咱們建立的Protocol。若是要採用多個Protocol,能夠在尖括號內引入多個Protocol名稱,並用逗號隔開便可。例如<ProcessDataDelegate,xxxDelegate>
 
m文件以下:
複製代碼
@implementation TestAppDelegate

- (void) processSuccessful: (BOOL)success{
    if (success) {
        NSLog(@"成功");
    }else {
        NSLog(@"失敗");
    }
}

@end 
複製代碼
因爲submitOrder方法是可選的,因此咱們能夠只實現processSuccessful。
 
Protocol通常使用在哪些場景呢?Objective-C裏的Protocol和Java語言中的接口很相似,若是一些類之間沒有繼承關係,可是又具有某些相同的行爲,則可使用Protocol來描述它們的關係。不一樣的類,能夠遵照同一個Protocol,在不一樣的場景下注入不一樣的實例,實現不一樣的功能。其中最經常使用的就是委託代理模式,Cocoa框架中大量採用了這種模式實現數據和UI的分離。例如UIView產生的全部事件,都是經過委託的方式交給Controller完成。根據約定,框架中後綴爲Delegate的都是Protocol,例如UIApplicationDelegate,UIWebViewDelegate等,使用時你們能夠留意一下,體會其用法。
 
使用Protocol時還須要注意的是:
一、Protocol自己是能夠繼承的,好比:
@protocol A
     -(void)methodA;
@end
@protocol B <A>
     -(void)methodB;
@end

若是你要實現B,那麼methodA和methodB都須要實現。 模塊化

二、Protocol是類無關的,任何類均可以實現定義好的Protocol。若是咱們想知道某個類是否實現了某個Protocol,還可使用conformsToProtocol進行判斷,以下:
[obj conformsToProtocol:@protocol(ProcessDataDelegate)] 
 
好吧,具體的語言特性此次就介紹這麼多。從某種意義上來講,Objective-C是一門古老的語言,發明於1980年。1988年,喬布斯的Next公司得到了Objective-C語言的受權,並開發出了Objective-C的語言庫和NEXTSTEP的開發環境。NextStep是以Mach和BSD爲基礎,Objective-C是其語言和運行庫,後來的事你們都清楚,蘋果買了Next,喬布斯迴歸蘋果,開始神奇的蘋果振興之路,NextStep成了Max OS X的基礎。之後發展愈來愈好,Objctive-C成了Apple的當家語言,如今基本上是Apple在維護Objctive-C的發展。
相關文章
相關標籤/搜索