Objective-C Protocols/协议
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
在上面的例子中,我们已经看到了如何调用和执行的delgate方法。启动startAction,一旦这个过程完成后,被称为委托方法processCompleted 操作完成。
在任何 iOS 或 Mac应用程序中,我们将永远不会有一个程序,没有委托实现。所以我们理解其重要委托的用法。委托的对象应该使用 unsafe_unretained 的属性类型,以避免内存泄漏。