委托(delegate)是一种对象,另一个类的对象会要求委托对象执行它的某些操作。
创建一个“NSObject”类别称为创建一个非正式协议。
任何实现“NSObject”类别中的方法的类的对象都可以成为委托对象。因为在Objective-C中所有的
类都是NSObject的子类。
当你想要向委托对象发送消息时,最好先检查该对象是否理解你将要发送的消息。
if ([delegate respondsToSelector: @selector(...)]
{
[delegate ...];
}
正式协议:通过在@protocol部分列出一组方法名来定义一个正式协议。通过在@interface声明中的类名之后列出
用尖括号括起来的协议名称,对象可以采用协议。当对象采用一个协议时,它承诺实现该协议中列出的每一个要求
实现的方法。如果你没有实现,编译器会提出警告,从而帮助你履行承诺。
当你使用了某个协议时,最好显示的声明,而不仅仅是实现了协议的方法(虽然可以这么做)。
下面这个例子中,没有声明采用协议FooDelegate,而只是实现了协议方法-(void)fun。这样虽然也能工作,
但这不是一个好的编程习惯。(应把Temp的声明改为@interface Temp:NSObject<FooDelegate>)
应该始终在类声明时指明我们使用的协议,这能明确表达我们的意图。这也是为什么要有正式协议的原因,否则
非正式协议就满足了。
/********************************************** Foo.h ***********************************************/ #import <Foundation/Foundation.h> @interface Foo : NSObject { NSInteger _t; } @property NSInteger t; @property (nonatomic, strong) id delegate; -(void) notify; @end @protocol FooDelegate -(void)fun; @end /********************************************** Foo.m ***********************************************/ #import "Foo.h" @implementation Foo @synthesize delegate; -(void)setT:(NSInteger)newt { self.t = newt; } -(NSInteger)t { NSLog(@"getter"); return self.t; } -(void) notify { NSLog(@"notify..."); if ([delegate respondsToSelector:@selector(fun)]) { [delegate fun]; } } @end /********************************************** Temp.h ***********************************************/ #import <Foundation/Foundation.h> @interface Temp : NSObject @end /********************************************** Temp.m ***********************************************/ #import "Temp.h" @implementation Temp -(void) fun { NSLog(@"Temp fun"); } @end /********************************************** main.m ***********************************************/ #import <Foundation/Foundation.h> #import "Foo.h" #import "Temp.h" int main (int argc, const char * argv[]) { @autoreleasepool { Foo *ob = [[Foo alloc] init]; Temp *t = [[Temp alloc] init]; ob.delegate = t; [ob notify]; } return 0; }