iOS开发-易错、需注意、罕见api

通知/代理/block实需处理

2018-06-18  本文已影响410人  RocketsChen

由于最近手上的项目页面间的互动感比较强,在处理问题的时候又思考一下老生常谈的三种回调处理方式。如下以假设实需为例:

Block:

warning: 防止内存循环

Delegate:

warning: 遵守协议,实现协议方法注意方法属性@required和@optional

Notification:

warning: 移除通知

三者比较:从消息的角度:Notification:“一对多”、“多对一”、Block和Delegate都是“一对一”。从结构上上:Block块状代码较为简洁更轻巧。从性能的角度:Block和Delegate比Notification性能高。

实需举例如:A控制器跳转到B —> B跳转到C —> C跳转到D D做一些事后返回B/A (点击)进入B界面 B根据D的改变产生回调。

如果只是简单的在实现角度上刚入门应该就可以解决了,一个通知搞定收工。但是这仅仅是D对B的一个需求。那么C对A、E对C等等;都以通知的方式去处理:那么频繁的发通知会导致很多不必要的麻烦如

以下用三种方式处理上面假设的需求:

✨代理:

@property (nonatomic, weak) id<DCBackDelegate> updateDelegate;//代理属性

@protocol DCBackDelegate <NSObject>

@optional

- (void)updateBackWithInfor:(NSString *)message; //协议方法

@end

一般我们先需要遵守代理协议。伪代码就是:委托对象.delegate = self。这里我们需要搞清楚谁是委托对象,谁是Self ? 从最终实在B页面调用协议方法的角度上来说也就是B声明的对象就是伪代码中的self。那委托对象自然而然就是D声明的对象了。代码如下:

//1:在D页面取出B对象
NSString *noteStr = @"我回来了";
for (DCSecondViewController *secondVc in self.navigationController.viewControllers) {
   if ([secondVc isKindOfClass:[DCSecondViewController class]]) {
       
       [self.navigationController popToViewController:secondVc animated:YES];
       
       //2:遵守协议
       self.updateDelegate = secondVc;
       
       //3:传值协议方法
       if (self.updateDelegate && [self.updateDelegate respondsToSelector:@selector(updateBackWithInfor:)]) {
           [self.updateDelegate updateBackWithInfor:noteStr];
       }
   }
}
@interface DCSecondViewController : UIViewController <DCBackDelegate>

#pragma mark - <DCBackDelegate> 代理
- (void)updateBackWithInfor:(NSString *)message
{
    [self alterSheetWithNote:message];
}

✨Block:

我们在B页面声明Block回调,在D页面调用,类似于用Block的方式在B.h页面声明一个方法在D调用。

//1:B.h声明
/** 更新B回调Block */
@property (nonatomic, copy) void(^updateBlock)(NSString *note);

//[图片上传中...(GIF.gif-bfd7ec-1529319531933-0)]
2:在D页面取出B对象
NSString *noteStr = @"我回来了";
for (DCSecondViewController *secondVc in self.navigationController.viewControllers) {
   if ([secondVc isKindOfClass:[DCSecondViewController class]]) {
       
       [self.navigationController popToViewController:secondVc animated:YES];
     
       //3.Block
       !secondVc.updateBlock ? : secondVc.updateBlock(noteStr);
       
       break;
   }
}
#pragma mark - Block
- (void)setUpBlockDo
{
    __weak typeof(self)weakSelf = self;
    self.updateBlock = ^(NSString *note) { //Block
        [weakSelf alterSheetWithNote:note];
    };
}

✨通知:

//1.发通知
dispatch_sync(dispatch_get_global_queue(0, 0), ^{

 [[NSNotificationCenter defaultCenter]postNotificationName:@"UPDATENOTE" object:nil userInfo:@{@"note" : noteStr}];
 
});
//2:接受通知:
#pragma mark - 通知回调
- (void)setUpAcceptNote
{
    __weak typeof(self)weakSelf = self;
    [[NSNotificationCenter defaultCenter] addObserverForName:@"UPDATENOTE" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {

        [weakSelf alterSheetWithNote:note.userInfo[@"note"]];
    }];
}

//3:移除
- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
演示
Ending...
上一篇 下一篇

猜你喜欢

热点阅读