delegate机制

iOS 码拜 10年前 (2015-05-01) 1818次浏览 0个评论

小弟刚刚接触oc,对于delegate机制不是太明白,求大神讲解一下delegate如何通过@property和synthesize实现呢?可以举例说明一下吗?比如说类A要实现输出,然后委托给B类来实现,通过@property来实现该怎么实现呢?
小弟感恩不尽。。。

delegate机制
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类就会在控制台打印出字符串。
delegate的好处是可以把事件触发和事件处理解耦,如果想把字符串写到文件中而不是打印在控制台,只需要加一个C类就好了:

@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,需要这么几步:
1.    创建一个delegate,在OC里,是通过正式协议来创建
2.    委托者声明一个delegate
3.    委托者调用delegate中的接口
4.    被委托者实现delegate
5.    把被委托者赋值给委托者

delegate机制
程序设计的所有目的都是为了灵活应变,让模块之间解耦就是其中的重中之重,你理解了delegate之后,就容易理解策略设计模式了
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
delegate机制
引用 3 楼 zhanglei5415 的回复:

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

原谅我我忍不住又想说一下
delegate与delegation是两种模式,即委托和代理。
委托是指对事件的处理,代理是控制对象的访问。
是两种模式

delegate机制
为什么@property中的属性不可以用copy呢?而其他的都可以用,还有就是if(self.delegate){ [self.delegate print]}这句可以直接用[delegate print]替代吗?

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类就会在控制台打印出字符串。
delegate的好处是可以把事件触发和事件处理解耦,如果想把字符串写到文件中而不是打印在控制台,只需要加一个C类就好了:

@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,需要这么几步:
1.    创建一个delegate,在OC里,是通过正式协议来创建
2.    委托者声明一个delegate
3.    委托者调用delegate中的接口
4.    被委托者实现delegate
5.    把被委托者赋值给委托者

delegate机制
为什么@property中的属性不可以用copy呢?
因为copy也是强引用,而且delegate一般都不会实现NSCopying协议,对没有实现NSCopying协议的对象调用copy会直接报错的;就算你让delegate实现NSCopying协议,也没有任何好处,这么做之后,等于让A类在内部管理B类,这个依赖关系就加重了,同时,也不应该出现被委托者在委托者之前被释放的情况。

还有就是if(self.delegate){ [self.delegate print]}这句可以直接用[delegate print]替代吗?
可以的,用if判断delegate的引用为nil其实没有意义,你最好用respondsToSelector:方法判断下delegate有没有实现该接口,因为协议申明的接口不一定会被全部实现。


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明delegate机制
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!