NSNotification、Block、Delegate和KVO.

iOS开发中数据传递的方法有很多种,我这里整理一下常用的NSNotification、Block、Delegate和KVO四种方式,仅供参考,具体使用要看开发中的需求,以及项目业务逻辑的需要.希望在适当的场景和业务下选择合适的方式去提高开发效率.

Block:

block是OC中一种对象和对象的通信方式,是一对一的关系.可以用于控制器与控制器的逆向传递数据。相比较代理而言的话,Block更加简洁灵活一点,不需要定义繁琐的协议方法,但通信事件比较多的话,建议使用Delegate;用block的话,一定要注意self的使用,防止循环引用导致的内存泄露.

用法:在a类中1,定义和2,回调block,在b类中3,实现block.

举例:
一, 按钮的触发事件.
1,定义block(有参数无返回值类型)

@property (nonatomic, copy) void(^didSelectDetailButton)(UIButton *sender);

2,block的回调.

- (void)pressDetailBtn:(UIButton *)sender{
  
    if (self.didSelectDetailButton) {
        self.didSelectDetailButton(sender);
    } 
}

3,block的具体实现.

   cell.didSelectDetailButton = ^(UIButton *sender) {
        
        SALookHaveSharedDetailController *haveVC = [SALookHaveSharedDetailController new];
        haveVC.dataArray = detailArray.mutableCopy;
        [weakSelf.navigationController pushViewController:haveVC animated:YES];
    };

二,block从后向前传值
1、在第二个视图控制器的.h文件中定义声明Block属性(block的定义):

//定义block
@property (nonatomic,copy) void (^NextViewControllerBlock)(NSString *tfText);

2, .m(block 的回调)

- (IBAction)BtnAction:(id)sender {
   
    //判断block是否为空
    if (self.NextViewControllerBlock) {
        self.NextViewControllerBlock(self.inputTF.text);
    }    [self.navigationController popViewControllerAnimated:YES];
}

3, 第一个控制器(block的实现)

- (IBAction)btnClicked:(id)sender {

NextViewController*nextVC =[[NextViewController alloc]init];
nextVC.NextViewControllerBlock= ^(NSString *tfText){ self.nextVCInfoLabel.text=tfText; }; [self.navigationController pushViewController:nextVC animated:YES];
}

代理:

delegate是是一对一的关系,通过setDelegate来设置代理对象,最典型的例子是常用的TableView.用代理的话,可以接收到调用协议方法的返回值,它定义的方法要按照一定的规范来写,这样易读性非常好,利于后期项目的维护以及修改。相比较而言代码量比较大.

用法:
在a类中1,定义代理和2,回调,在b类中3,指定代理对象4,遵循协议5,实现代理方法.

举例:
1,定义代理

@property (nonatomic, weak) id<SAAddJobPointRuleCellDelegate> delegate; 

@protocol SAAddJobPointRuleCellDelegate <NSObject>

- (void)tapAddJobPointRule:(SAAddJobPointRuleCell *)ruleCell;

@end

2,回调

- (void)tapAddAction:(UITapGestureRecognizer *)sender{
    
    if ([self.delegate respondsToSelector:@selector(tapAddJobPointRule:)]) {
        [self.delegate tapAddJobPointRule:self];
    }
}

3,指定代理对象

    self.cardSceneView.delegate = self;

4,遵循协议

@interface TestController ()<TestCardSceneViewDelegate>

5,实现代理方法

- (void)tapAddJobPointRule:(SAAddJobPointRuleCell *)ruleCell{
    self.isSelectReset = NO;
    SAGetAllShipperController *allVC = [SAGetAllShipperController new];
    allVC.selectIndex = ruleCell.cellIndex;
      [self.navigationController pushViewController:allVC animated:YES]; 
}

KVO:

KVO( Key-Value Observing),是Foundation框架提供的一种机制,可以一对多.使用KVO,可以方便地对指定对象的某个属性进行观察,(一个对象能够观察另外一个对象的属性的值,并且能够发现值的变化。)被观察的属性对应的对象 来 添加 和 移除 观察者.只能用来对属性作出反应,而不会用来对方法或者动作作出反应只负责把通知发出去,至于其他的事情就不管了,因此他们没有返回值.注意:我们观察的属性必须使用strings来定义.

用法:
1.由被观察的对象调用方法, 添加观察者:addObserver:forKeyPath:options:context:
2.一旦被观察的属性发生改变, 系统会调用这个方法:observeValueForKeyPath:ofObject:change:context:方法
3.解除观察者身份:removeObserver:forKeyPath:context:

举例:
1,定义属性:

@interface ShipperModel : NSObject

@property (nonatomic, copy) NSString *togetherString;

@property (nonatomic, copy) NSString *separateString;

@end

2,添加观察者

 [_shipperModel addObserver:self forKeyPath:@"togetherString" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL];
  [_shipperModel addObserver:self forKeyPath:@"separateString" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL];

3,监测变化

#pragma mark -
#pragma mark - KVO
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context { 
}

4,解除身份

- (void)dealloc {
   
    [self.shipperModel removeObserver:self forKeyPath:@"togetherString"];
    [self.shipperModel removeObserver:self forKeyPath:@"separateString"]; 
}

通知:

NSNotification是苹果提供的一种消息机制, 观察者只要向消息中心注册, 即可接受其他对象发送来的消息,消息发送者和消息接受者两者可以互相一无所知,完全解耦。NSNotification可以应用于任意时间和任何对象,可以一对多.但只负责把通知发出去,至于其他的事情就不管了,因此他们没有返回值

用法:a类中创建和移除通知,以及响应通知所要做的操作.b类通知中心发送通知
1,注册一个观察者
2,给通知中心发送一个消息
3,清除观察者

举例:
1,通知中心添加观察者

- (void)viewDidLoad {
    [super viewDidLoad];  
     [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(fifthStepAction:) name:@“fifthStep” object:nil];
}

2,响应通知所要做的事件操作.

//  object 和 userInfo可以带来想要接收的值
- (void)fifthStepAction:(NSNotification *)noti{
    
    NSDictionary *dict = noti.userInfo;
    self.isSettedSecondDismension = [dict[@"isSetted"] boolValue];
    self.typeName = dict[@"typeName"];
}

//- (void)fifthStepAction:(NSNotification *)noti{
    
//    self.isFromAddSureBack = [noti.object boolValue];
//}

3,移除通知

- (void)dealloc{
    [[NSNotificationCenter defaultCenter]removeObserver:self]; 
}

4,通知中心发送通知

// object 和 userInfo可以带来想要接收的值
  if (self.isTest) {
            NSNotification *noti = [[NSNotification alloc]initWithName:@“fifthStep”  object:nil userInfo:dict];
            [[NSNotificationCenter defaultCenter] postNotification:noti];
           
            [self.navigationController popToViewController:targetVC animated:YES]; 
        }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容

  • KVO就是cocoa框架实现的观察者模式,一般同KVC搭配使用,通过KVO可以监测一个值的变化,比如View的高度...
    攻城狮GG阅读 5,315评论 0 7
  • 设计模式 1.delegate和notification什么区别,什么情况使用? 2.描述一下KVO和KVC。 K...
    丶逐渐阅读 1,953评论 3 2
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,134评论 30 470
  • 基础 1. 为什么说Objective-C是一门动态的语言? 2. 讲一下MVC和MVVM,MVP? 3. 为...
    波妞和酱豆子阅读 3,311评论 0 46
  • 熬中药是一门学问。很多东西,是医生必须告诉你但没有时间和耐心仔细跟你讲的;很多东西是病人想问又不敢问的。我今将其罗...
    乔墨与鹿阅读 533评论 1 7