小弟刚刚接触oc,对于delegate机制不是太明白,求大神讲解一下delegate如何通过@property和synthesize实现呢?可以举例说明一下吗?比如说类A要实现输出,然后委托给B类来实现,通过@property来实现该怎么实现呢? |
|
100分 |
delegate是委托,就是当一个对象遇到某种事件的时候,自己(委托者)不处理,交给另一个对象(被委托者)来处理。委托者和被委托者之间就通过delegate来沟通。
比如有这样一个A类: @protocol TestDelegate <NSObject> - (void)printForText:(NSString *)text; @end //////////////////////////////////////////////////////// @interface TestA : NSObject @property (nonatomic, weak) id<TestDelegate> delegate; @end //////////////////////////////////////////////////////// @implementation TestA - (void)invoke { if (self.delegate) { [self.delegate printForText:@"This is a test."]; } } @end A类有一个invoke方法,我们假设它会在某种情况下被调用,比如接收到了用户输入的字符串,这个时候有A类并不知道该如何处理这个字符串,就需要B类出场了: @interface TestB : NSObject <TestDelegate> @end @implementation TestB - (void)printForText:(NSString *)text { NSLog(@"%@", text); } @end 实现了TestDelegate,然后在main方法里把A类的delegate设为B类: int main(int argc, const char * argv[]) { @autoreleasepool { TestA *a = [TestA new]; TestB *b = [TestB new]; a.delegate = b; [a invoke]; } return 0; } 这样一来,当A类的invoke被调用的时候,B类就会在控制台打印出字符串。 @interface TestC : NSObject <TestDelegate> @end @implementation TestC - (void)printForText:(NSString *)text { [text writeToFile:@"File" // 伪代码,此处应该是一个Document目录下的文件路径 atomically:YES encoding:NSUTF8StringEncoding error:nil]; } @end 而A类、B类的代码都不需要作出改动。 |
程序设计的所有目的都是为了灵活应变,让模块之间解耦就是其中的重中之重,你理解了delegate之后,就容易理解策略设计模式了
|
|
Delegate ,又称为 委托或代理, 它是一种设计模式。oc中的代理是通过协议protocol 来表达的。委托是协议的一种,顾名思义,就是委托他人帮自己去做什么事。所以它是基于事件驱动的。
Delegate的用途: 用于改变或控制其他对象 。 Delegate Message 的命名: 发给Delegate的消息 通常带有(should, will, did) 之一。 should:期待delegate返回一个值; will:表示变化发生之前 要做的事情; did : 表示变化发生之后 要做的事情。 在UIKit框架中delegate被广泛应用,如:UITableView, UITextField, UITextView, UIAlertView, UIActionSheet ….. 等等 Delegate 可用在多个场景下,比如对象间的数据交互, 不同视图之间的行为交互。 若仅仅是数据交互, 可实现的方法还有很多。Delegate 尤其适用于视图之间的行为交互。 关于delegate 的问题,也有很多这样的帖子,也可以参见:http://bbs.csdn.net/topics/391003810 |
|
原谅我我忍不住又想说一下 |
|
为什么@property中的属性不可以用copy呢?而其他的都可以用,还有就是if(self.delegate){ [self.delegate print]}这句可以直接用[delegate print]替代吗?
delegate是委托,就是当一个对象遇到某种事件的时候,自己(委托者)不处理,交给另一个对象(被委托者)来处理。委托者和被委托者之间就通过delegate来沟通。 @protocol TestDelegate <NSObject> - (void)printForText:(NSString *)text; @end //////////////////////////////////////////////////////// @interface TestA : NSObject @property (nonatomic, weak) id<TestDelegate> delegate; @end //////////////////////////////////////////////////////// @implementation TestA - (void)invoke { if (self.delegate) { [self.delegate printForText:@"This is a test."]; } } @end A类有一个invoke方法,我们假设它会在某种情况下被调用,比如接收到了用户输入的字符串,这个时候有A类并不知道该如何处理这个字符串,就需要B类出场了: @interface TestB : NSObject <TestDelegate> @end @implementation TestB - (void)printForText:(NSString *)text { NSLog(@"%@", text); } @end 实现了TestDelegate,然后在main方法里把A类的delegate设为B类: int main(int argc, const char * argv[]) { @autoreleasepool { TestA *a = [TestA new]; TestB *b = [TestB new]; a.delegate = b; [a invoke]; } return 0; } 这样一来,当A类的invoke被调用的时候,B类就会在控制台打印出字符串。 @interface TestC : NSObject <TestDelegate> @end @implementation TestC - (void)printForText:(NSString *)text { [text writeToFile:@"File" // 伪代码,此处应该是一个Document目录下的文件路径 atomically:YES encoding:NSUTF8StringEncoding error:nil]; } @end 而A类、B类的代码都不需要作出改动。 |
|
为什么@property中的属性不可以用copy呢?
因为copy也是强引用,而且delegate一般都不会实现NSCopying协议,对没有实现NSCopying协议的对象调用copy会直接报错的;就算你让delegate实现NSCopying协议,也没有任何好处,这么做之后,等于让A类在内部管理B类,这个依赖关系就加重了,同时,也不应该出现被委托者在委托者之前被释放的情况。 还有就是if(self.delegate){ [self.delegate print]}这句可以直接用[delegate print]替代吗? |