一.各自特点
通知(NSNotification):“一对一或一对多”,在APP中,很多控制器都需要知道一个事件,应该用通知; 但是一定要注意,一旦接收消息的对象多了,就难以控制了,可能有你不希望的对象接受了消息并做了处理,另外一旦注册了观察者,在dealloc里面一定要移除
delegate:
1,“一对一”,对同一个协议,一个对象只能设置一个代理delegate,所以单例对象就不能用代理;
2,代理更注重过程信息的传输:比如发起一个网络请求,可能想要知道此时请求是否已经开始、是否收到了数据、数据是否已经接受完成、数据接收失败等信息
block:
1:写法更简练,不需要写protocol、函数等等
2,block注重结果的传输:比如对于一个事件,只想知道成功或者失败,并不需要知道进行了多少或者额外的一些信息
3,block需要注意防止循环引用:
ARC下这样防止:
__weak typeof(self) weakSelf = self;
[yourBlock:^(NSArray *repeatedArray, NSArray *incompleteArray) {
[weakSelf doSomething];
}];
非ARC
__block typeof(self) weakSelf = self;
[yourBlock:^(NSArray *repeatedArray, NSArray *incompleteArray) {
[weakSelf doSomething];
}];
delegate针对one-to-one关系,并且reciever可以返回值(通常是YES或NO)给sender;
notification 可以针对one-to-one/many/none,reciever无法返回值给sender;
所以,delegate用于sender希望接受到reciever的某个功能反馈值,notification用于通知多个object某个事件。
最典型的特征是,delegate方法往往需要关注返回值,也就是delegate方法的结果。比如-windowShouldClose:,需要关心返回的是yes还是no。所以delegate方法往往包含should这个很传神的词。也就是好比你做我的delegate,我会问你我想关闭窗口你愿意吗?你需要给我一个答案,我根据你的答案来决定如何做下一步。相反的,notification最大的特色就是不关心接受者的态度,我只管把通告放出来,你接受不接受就是你的事情,同时我也不关心结果。所以notification往往用did这个词汇,比如NSWindowDidResizeNotification,那么nswindow对象放出这个notification后就什么都不管了也不会等待接受者的反应。
二.代码分析
代理模式
作为IOS中最常见的通讯模式,代理几乎无处不在。
看实例
这里有一个数组,我们首先通过代理的方式将数组传递到其他方法中去。
设置协议及方法
@protocol CallBackDelegate;
@interface ViewController : UIViewController
@property (weak, nonatomic) id<CallBackDelegate> delegate;
@end
@protocol CallBackDelegate <NSObject>
- (void)showArrayWithDelegate:(NSArray *)array;
@end
@interface ViewController () <CallBackDelegate>
点击按钮传递数组让其显示
- (IBAction)delegateCallBack
{
NSDictionary *dict = @{@"array": @[@"Chelsea", @"MUFC", @"Real Madrid"]};
NSArray *array = dict[@"array"];
[self.delegate showArrayWithDelegate:array];
}
调用,显示
- (void)showArrayWithDelegate:(NSArray *)array
{
_outputLabel.text = array[2];
}
最重要也是最容易忽略的,就是一定要设置delegate的指向。
完成后屏幕显示
通知中心的方式可以不用设置代理,但是需要设置观察者和移除观察者。
代码
- (IBAction)callBack
{
NSDictionary *dict = @{@"array": @[@"Chelsea", @"MUFC", @"Real Madrid"]};
NSArray *array = dict[@"array"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"OutputArrayNotification" object:array];
}
注册和移出观察者
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(outputWithNote:) name:@"OutputArrayNotification" object:nil];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"OutputArrayNotification" object:nil];
}
显示
- (void)outputWithNote:(NSNotification *)aNotification
{
NSArray *receiveArray = [aNotification object];
_outputLabel.text = receiveArray[0];
}
什么是Block:从C的声明符到Objective-C的Blocks语法
块代码以闭包得形式将各种内容进行传递,可以是代码,可以是数组无所不能。块代码十分方便将不同地方的代码集中统一,使其易读性增强。
来看这里怎么进行数组传递。
typedef void (^Arr_Block)(NSArray *array);
- (void)showArrayUsingBlock:(Arr_Block)block
{
NSDictionary *dict = @{@"array": @[@"Chelsea", @"MUFC", @"Real Madrid"]};
NSArray *array = dict[@"array"];
block(array);
}
调用方法,显示
- (IBAction)blockCallBack
{
[self showArrayUsingBlock:^(NSArray *array) {
_outputLabel.text = array[1];
}];
}