介绍
Protocols 通常的用法是定义一些方法然后在别的CLASS进行实装。大家可能比较熟悉tableview, 你的CLASS实装cellForRowAtIndexPath 方法来通过访问cell content向table插入数据 – the cellForRowAtIndexPath 方法就是定义UITableViewDataSource里的protocol.
Protocols 定义
让我们理解一下这个预设的例子,目的是展示一下在哪里,什么时候使用protocol。假设我们有class在执行提取数据,再假设这个class被别的class调用去执行提取数据
那么这时候protocol就会发挥作用,我们通过它来知道什么时候提取数据的过程结束了。
在调用方,有一方法processSuccessful被定义在protocol,当提取数据的过程结束,这个方法将被实装并被调用。
这个例子中, 在被定义了protocol的CLASS中, 有个方法startSomeProcess, 它简单启动一个timer并且过5秒后调用processComplete。在processComplete,当提取数据过程结束,调用方会通过delegate得到通知。
它们怎么工作的
app delegate 将要建立一个ClassWithProtocol的实例。它将自己作为delegate,然后调用startSomeProcess方法。当protocolTest结束提取数据,5秒钟后在app delegate里processSuccessful将会被调用。
Protocols 通常的用法是定义一些方法然后在别的CLASS进行实装。大家可能比较熟悉tableview, 你的CLASS实装cellForRowAtIndexPath 方法来通过访问cell content向table插入数据 – the cellForRowAtIndexPath 方法就是定义UITableViewDataSource里的protocol.
Protocols 定义
例子
注意,这里的delegate被定义成ID。
#import <Foundation/Foundation.h>
@protocol ProcessDataDelegate <NSObject>
@required
- (void) processSuccessful: (BOOL)success;
@end
@interface ClassWithProtocol : NSObject
{
id <ProcessDataDelegate> delegate;
}
@property (retain) id delegate;
-(void)startSomeProcess;
@end
Protocol 实装
最少需要做两件事情,一个是synthesize the delegate实例变量。二是调用在protocol里定义的方法
看看 ClassWithProtocol.m 的例子
#import "ClassWithProtocol.h"
@implementation ClassWithProtocol
@synthesize delegate;
- (void)processComplete
{
[[self delegate] processSuccessful:YES];
}
-(void)startSomeProcess
{
[NSTimer scheduledTimerWithTimeInterval:5.0 target:self
selector:@selector(processComplete) userInfo:nil repeats:YES];
}
@end
那么这时候protocol就会发挥作用,我们通过它来知道什么时候提取数据的过程结束了。
在调用方,有一方法processSuccessful被定义在protocol,当提取数据的过程结束,这个方法将被实装并被调用。
这个例子中, 在被定义了protocol的CLASS中, 有个方法startSomeProcess, 它简单启动一个timer并且过5秒后调用processComplete。在processComplete,当提取数据过程结束,调用方会通过delegate得到通知。
#import <UIKit/UIKit.h>
#import "ClassWithProtocol.h"
@interface TestAppDelegate : NSObject <UIApplicationDelegate, ProcessDataDelegate>
{
UIWindow *window;
ClassWithProtocol *protocolTest;
}
@property (nonatomic, retain) UIWindow *window;
@end
采用 Protocol
为了让例子简单些,使用applicaton delegate 作为class采用protocol。
需要注意的是,ProcessDataDelegate是作为class的interface的,说明这个class将附属于protocol,protocol的定义里有 @required 方法,意思是说任何class如果采用protocol的话,必须实装processSuccessful方法(如果不实装的话,会有编译警告)。
#import "TestAppDelegate.h"
#import "ClassWithProtocol.h"
@implementation TestAppDelegate
@synthesize window;
UITableViewDelegate
- (void)processSuccessful:(BOOL)success;
{
NSLog(@"Process completed");
}
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
// Create and initialize the window
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
protocolTest = [[ClassWithProtocol alloc] init];
[protocolTest setDelegate:self];
[protocolTest startSomeProcess];
[window makeKeyAndVisible];
}
- (void)dealloc
{
[window release];
[super dealloc];
}
@end
app delegate 将要建立一个ClassWithProtocol的实例。它将自己作为delegate,然后调用startSomeProcess方法。当protocolTest结束提取数据,5秒钟后在app delegate里processSuccessful将会被调用。