代理 通知 Block区别

一.各自特点

通知(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中最常见的通讯模式,代理几乎无处不在。

142449_Ja2G_2631712.png

看实例

这里有一个数组,我们首先通过代理的方式将数组传递到其他方法中去。

设置协议及方法

@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的指向。

完成后屏幕显示



使用通知中心


通知中心的方式可以不用设置代理,但是需要设置观察者和移除观察者。

142514_lMUk_2631712.png

代码

- (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

什么是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];
    }];
}


转载于:https://my.oschina.net/AngusTing/blog/617626

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值