[iOS開發必備知識之] Category & Protocol


本文來源:http://devnote.me/page/4/

http://blog.codingmylife.com/?p=41

Categories

1
2
3
4
5
6
7
8
#import “ClassName.h”
@interface ClassName ( CategoryName )
// method declarations
@end
#import “ClassName+CategoryName.h”
@implementation ClassName ( CategoryName )
// method definitions
@end

For example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@interface MyObject : NSObject{
NSNumber *number;
}
- (NSNumber *)number;
@end
@interface MyObject (Setter)
- (void)setNumber:(NSNumber *)newNumber;
@end
@implementation MyObject
- (NSNumber *)number{
return number;
}
- (void)setNumber(NSNumber *)newNumber{
number = newNumber;
}
@end

Protocol

1
2
3
4
5
6
7
8
@protocol MyProtocol
- (void)requiredMethod;
@optional
- (void)anOptionalMethod;
- (void)anotherOptionalMethod;
@required
- (void)anotherRequiredMethod;
@end

For example

1
2
3
4
5
6
7
8
9
10
Inherit multiple protocol. @interface Formatter : NSObject Instance. Protocol *myXMLSupportProtocol = @protocol(MyXMLSupport);
Check if methods are declared
if(![receiver conformsToProtocol:@protocol(MyXMLSupport)]){
//Object does not conform to MyXMLSupport protocol
//If you are expecting receiver to implement methods declared in the
//MyXMLSupport protocol, this is probably an error
}
 
-(NSString*)formattingService:(id)anObject;
———————————————————————

http://icocoa.cn/ocsection/oc-tips/60-category-vs-protocol

Category
Category提供了一種比繼承(inheritance)更爲簡潔的方法來對class進行擴展,我們可以爲任何已經存在的class添加方法(不包括數據成員)卻不需要訪問該class的實現文件。
新添加的方法和原有的方法具有同等的地位,可以訪問class的數據成員,並且完全植入到class的繼承體系之中,子類同樣會繼承新添加的方法。 利用category對類進行擴展可以避免使類的繼承體系過於臃腫,複雜,降低了維護成本。另外,新添加的方法如果和已經存在的方法具有相同的 prototype,那麼新添加的方法將會覆蓋已經存在的方法,也就是category使得使得在沒有源文件時修改已存在class的 functionality或者清除bug成爲可能,所有該class的對象的行爲都將發生變化,這一點是繼承無法達到的。

Category的缺點:
如果一個已經存在的方法被新方法覆蓋,那麼將沒有任何途徑可以對舊方法進行調用。這一點和繼承是不同的,子類對父類成員函數重寫(override),但我們依然可以對父類中的被重寫的成員函數進行調用。
如果有多個category對同一個class的成員函數進行重寫,那麼具體的行爲是未定義。
Category的應用:
對類進行擴展或patch。
使用category或(anonymous category)來模擬實現private method。
使用category(informal protocol)來實現delegation,在cocoa framework中就大量使用了category來聲明delegate methods。
利用category把一個龐大的class劃分爲小塊兒來分別進行開發,從而將functionality更好的進行劃分,利於維護。

Protocol
根據字面意思,protocol就是一個協議,一個contract。一個class如果採用了某個protocol,那麼它就必須要遵守這個協 議。從另外一個角度,只要我遵守了某個protocol或者標準,那我就可以和其它的類進行交互,而且其它類並不需要知道我的內部是如何實現的,例如 一套組合音響,只要其中的dvd,錄音機等設備採用的是標準接口,那麼它就可以很輕易的被放入這個音響系統中,發揮自己的功能。回到objective c,在cocoa touch framework中利用protocol聲明delegate methods是同樣的道理,cocoa touch framework,你們想要提供自定義功能或者響應某個事件嗎?很簡單,只要你們的功能遵守我提供的protocol。(注意,這裏之所以採 用protocol來聲明delegate methods,而不是cocoa framework中使用informal protocol(category),是因爲objective c 2.0 引入了@optional methods,iphone又是在objective c 2.0之後出來的,所以cocoa touch framework中就用protocol替代informal protocol來聲明delegate methods。)其實plugin,回調函數都是和protocol相同的思路。

另一方面,objective c只支持單一繼承,protocol提供了一個途徑來達到多重繼承的目的。

另一介紹 Protocol文章:

http://www.cocoachina.com/bbs/read.php?tid-50601.html

協議,是通過網絡,計算機使用者進行通訊後,互相進行約定規定的集合。兩個類進行通訊,用協議就比較方便。下面是 CocoaChina 版主“angellixf”爲新手寫的協議入門介紹以及代碼例子,希望對剛入門開發者有所幫助
一、說明
1.協議聲明瞭可以被任何類實現的方法
2.協議不是類,它是定義了一個其他對象可以實現的接口
3.如果在某個類中實現了協議中的某個方法,也就是這個類實現了那個協議。
4.協議經常用來實現委託對象。一個委託對象是一種用來協同或者代表其他對象的特殊對象。
5:委託,就是調用自己定義方法,別的類來實現。
6.新特性說明
@optional預編譯指令:表示可以選擇實現的方法
@required預編譯指令:表示必須強制實現的方法

二、定義
.h

1
2
3
4
5
6
7
8
@protocol ContactCtrlDelegate
-(void)DismissContactsCtrl;
@end
 
@interface ContactsCtrl : UIViewController {
    id <ContactCtrlDelegate> delegate;
}
@property (nonatomic, assign) id <ContactCtrlDelegate> delegate;

.m

1
@synthesize delegate;

三、例子
例如:UITextView

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@protocol UITextViewDelegate <NSObject>
 
@optional
 
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView;
- (BOOL)textViewShouldEndEditing:(UITextView *)textView;
 
- (void)textViewDidBeginEditing:(UITextView *)textView;
- (void)textViewDidEndEditing:(UITextView *)textView;
 
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
- (void)textViewDidChange:(UITextView *)textView;
 
- (void)textViewDidChangeSelection:(UITextView *)textView;
 
@end

如果要調用以上這些方法,就必須設置UITextView的委託:TextView.delegate = self;

四、Demo

1、ContactsCtrl.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#import <UIKit/UIKit.h>
 
//定義協議
@protocol ContactCtrlDelegate
-(void)DismissContactsCtrl;
@end
 
@interface ContactsCtrl : UIViewController {
    IBOutlet UINavigationBar *ContactNavBar;
    id <ContactCtrlDelegate> delegate;
}
@property (nonatomic, assign) id <ContactCtrlDelegate> delegate;
 
-(IBAction)canCelBtn:(id)sender;
@end
1
 
2、ContactsCtrl.m
1
@implementation ContactsCtrl
@synthesize delegate;
 
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
    ContactNavBar.topItem.prompt = @"選取聯繫人發送短信";
}
 
//調用協議中的方法
-(IBAction)canCelBtn:(id)sender{
    [delegate DismissContactsCtrl];
}

3、ProtocolDemoCtrl.h

1
2
3
4
5
#import <UIKit/UIKit.h>
#import "ContactsCtrl.h"
@interface ProtocolDemoCtrl : UIViewController <ContactCtrlDelegate>{//添加委託
    ContactsCtrl *contactsView;
}

4、ProtocolDemoCtrl.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#import "ProtocolDemoCtrl.h"
#define BARBUTTONADD(SELECTOR) [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:SELECTOR] autorelease];
 
@implementation ProtocolDemoCtrl
@synthesize contactsView;
 
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationItem.rightBarButtonItem = BARBUTTONADD(@selector(addContactAction:));
}
 
- (void)addContactAction:(id)sender{
    ContactsCtrl *contactView = [[ContactsCtrl alloc] initWithNibName:@"ContactsCtrl" bundle:nil];
    self.contactsView = contactView;
    contactsView.delegate = self;//設置委託
    [self presentModalViewController:contactsView animated:YES];
    [contactView release];
}
 
//實現ContactCtrlDelegate協議中的方法
-(void)DismissContactsCtrl{
    [contactsView dismissModalViewControllerAnimated:YES];
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章