Objective-C 協議



Objective-C 允許你定義協議,這些協議聲明瞭特定情況下預期使用的的方法。協議在符合該協議的類中實現。

一個簡單的例子是一個網路 URL 處理類,它將有一個包含諸如 processCompleted 代理方法的協議,該方法在網路 URL 獲取操作完成後通知呼叫類。

下面顯示了協議的語法。

@protocol ProtocolName
@required
// list of required methods
@optional
// list of optional methods
@end

@required 關鍵字下的方法必須在符合該協議的類中實現,而 @optional 關鍵字下的方法則可以選擇實現。

以下是類符合協議的語法

@interface MyClass : NSObject <MyProtocol>
...
@end

這意味著 MyClass 的任何例項不僅會響應在介面中專門宣告的方法,而且 MyClass 還提供了 MyProtocol 中必需方法的實現。無需在類介面中重新宣告協議方法 - 採用協議就足夠了。

如果需要一個類採用多個協議,可以將它們指定為用逗號分隔的列表。我們有一個代理物件,它儲存實現該協議的呼叫物件的引用。

下面是一個例子。

#import <Foundation/Foundation.h>

@protocol PrintProtocolDelegate
- (void)processCompleted;

@end

@interface PrintClass :NSObject {
   id delegate;
}

- (void) printDetails;
- (void) setDelegate:(id)newDelegate;
@end

@implementation PrintClass
- (void)printDetails {
   NSLog(@"Printing Details");
   [delegate processCompleted];
}

- (void) setDelegate:(id)newDelegate {
   delegate = newDelegate;
}

@end

@interface SampleClass:NSObject<PrintProtocolDelegate>
- (void)startAction;

@end

@implementation SampleClass
- (void)startAction {
   PrintClass *printClass = [[PrintClass alloc]init];
   [printClass setDelegate:self];
   [printClass printDetails];
}

-(void)processCompleted {
   NSLog(@"Printing Process Completed");
}

@end

int main(int argc, const char * argv[]) {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   SampleClass *sampleClass = [[SampleClass alloc]init];
   [sampleClass startAction];
   [pool drain];
   return 0;
}

現在,當我們編譯並執行程式時,我們將得到以下結果。

2013-09-22 21:15:50.362 Protocols[275:303] Printing Details
2013-09-22 21:15:50.364 Protocols[275:303] Printing Process Completed

在上面的例子中,我們看到了代理方法是如何被呼叫和執行的。它從 startAction 開始,一旦程序完成,就會呼叫代理方法 processCompleted 來通知操作已完成。

在任何 iOS 或 Mac 應用程式中,我們都不會實現沒有代理的程式。因此,理解代理的使用非常重要。代理物件應該使用 unsafe_unretained 屬性型別來避免記憶體洩漏。

廣告