Delegation ,Block,NSNotification

1.delegation:
Delegation 是一种很清晰回调形式,从 Protocol 的建立,到之后的引用,和对于 delegate 声明的变量处理,都非常具有条理。建立完 Delegation 之后,其他方法在调用的时候会很清晰整个回调的流程和处理。在处理一些延迟回调或者触发回掉的时候,声明调用的类里面的回调方法在编写时可以按照很独立的逻辑在制作。在使用 Delegation 的时候,一个回调方法可以对应多个不同的 Delegation ,这不仅简化了编程过程,也让能回调处理更加清晰。
Delegation 不好的地方在于,在类中调用 delegate 方法的时候,需要对 delegate 本体进行一定的验证核对,防止出现方法对象为空的情况,再一个就是受制于 performSelector 这个 selector 方法,回掉返回的参数被限制在了 NS 类的范围内,数量也很有限(当然可以用直接调用方法的形式在绕过,并不推荐;也可以用 Array 套着传, 不过这样需要有文档支持,不然不够清晰,回调方法也需要独立的验证,故也不推荐):
if (self.delegate && [self.delegate respondsToSelector:@selector(ABC:)]){
[self.delegate performSelector:@selector(ABC:) withObject:@"ABC"];
}
//需要验证代理是否为空,同时验证代理方法是否存在
这个问题在 Swfit 中有了很不错的解决:
delegate?.ABC?(@"ABC")
至于说 Delegation 的另外一个问题,那就是使用了 Delegation 之后,代码阅读变成了一件很困难的事情,你需要在不同的 Class 文件中一次次的跳转来理解整个代码思路,要知道糟糕的 XCode 还经常会跳错方法(Command + 点击跳转,跳到了同名的其他方法),导致代码可读性的下降。要说的话,这一点在 Swift(2.2)版本中有一定的优化,不过 Swift 的 Selector 还在修正中,之后也许会在对于 Delegation 的可读性上做更多的优化。
最后一个比较核心的问题就在于,在一批变量声明了代理之后,在代理回掉被执行时,你是不太好知道这个变量究竟是这一批中的哪一个的。这也就是为什么苹果在制作 delgate 和 datasource 的时候都会在代理方法的返回值中带上声明代理类本身的原因。
2.block:
Block 是一种很好用的回掉方式,其解决了 Delegation 在确认声明对象上的问题,由于 Block 回调方法一般都跟随在声明之后,所以可以很快确认回调来源,通过 __block 声明的变量也可以很方便的穿越到回调方法中进行使用,代码可读性上,一般来说使用 Block 的代码比使用 Delegation 的代码可读性更强(当然你也可以声明 Block 回调方法对应变量,然后按照和 Delegation 差不多的方法来调用他)。
Block 的缺陷主要就在于使用 ARC 情况下的循环引用。从某种程度上来说, Block 回调的方法内变量实际上是关联在声明 Block 的类里面的,但 Block 回调方法本身是在使用 Block 的类中的,同时使用类的 self 本身是可以在 Block 回调方法中被请求的,这里就会出现使用类 A 引用声明类 B ,B 在关联的 Block 中又引用了使用类 A ,这样一个循环之后引用可以无限循环下去,在这种无限循环的引用下, ARC 就无法知道 A 和 B 的确切弃用时间,所以 A 和 B 会在内存中永远存活下去,直到进程被消灭。所以,在很多时候,我们必须要使用 __weak 来声明一个 weakself ,来帮助 ARC 判断内存回收的时间。
这里要指出的是, Block 的回调方法也是可以复用,创建回调方法这一套东西在 Objective-C 中是继承于 C 样式的,一般来说,这个东西是没人用。[4]
void (^simpleBlock)(id responseObject) = ^(id responseObject){
NSLog(@"This is a block");
};
//这里创建了 simpleBlock 之后就可以像 Delegation 回调方法那样在各种回调声明中使用了

3.nsnotification;
NSNotification 本身是一个非常强大的回调,因为他的回调是全局而且一对多的,广播的特性使得很多时候使用 NSNotification 能一次解决大面积的问题。
至于说 NSNotification,就和上面说到的一样,也主要是在于他的全局广播属性和权限机制。
在使用 NSNotification 的时候,注册完回调方法之后,开发者需要自行对注册进行取消操作。比如说你注册一个 A 方法到 B 通知,由于某些原因 A 方法所在的类被 ARC 回收掉了,那么在 B 通知被触发的时候,由于 A 的通知注册信息还在,就会出现调用了非法的内存地址的情况。
至于说 NSNotification 的权限问题,对于写类的人来说是比较头疼的,很多时候只能靠文档和调用者的自觉,出于权限考虑,如果不是特别需求全局广播这个特性,一般不太建议使用 NSNotification。
NSNotification 由于自身的限制,在回调可以传递的内容上也存在数量和内容的限制,虽然可以通过 Array 的方法绕过,但这样在代码可读性就会有折扣,对于文档也需要有要求,回调方法中还需要验证。

4如何选择使用三者;
对于初级的开发人员来说,关键在于使用习惯。如果你从其他语言转到 Objective-C 或者 Swift ,相信 Delegation 肯定让你觉得更加亲切,那么在初级阶段请使用好这个语法糖,多用,多去理解;如果你用着 AFNetworking 看着其他老前辈的说法用 Block 觉得效率很高很开心,那就开心的用,直到你被循环引用烦到了为止(笑);如果你用 NSNotification ……你还是别用了。然后,在你代码写多了之后,你可以开始尝试接触其他回调方式,去感受这些回调方式的不同。

对于中级的开发人员,关键在于对于回调流程的理解。
你要知道你的回调是一个什么性质的回调,如果这个回调是一个不定期触发,或者会多次触发的,那么 Delegation 应该更适合;如果这个回调是一个一次性的,并且和调用方法是单线性关系的,那么 Block 应该更适合;如果这个回调是广播性质的,需要很多个不同的类都接收到,那么 NSNotification 更适合。
在不同的执行线(不是线程),不同的执行次数、执行数量上的区别,是鉴别使用哪一种回调的最好判断方法。
对于 Block 来说,他的执行线应该是和调用方法、回调方法连续在一起的;对于 Delegation 和 NSNotification 来说,他的执行线可以是连续的,也可以是调用方法和回调方法之间有很长的间隔,或者说回调方法在执行线上会多次出现。

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

推荐阅读更多精彩内容