网络层block,delegate之优劣分析

正常情况下,

block 缺点:

1、block很难追踪,难以维护

2、block会延长先关对象的生命周期

  block会给内部所有的对象引用计数+1,

  一方面会带来潜在的循环引用(retain cycle),不过我们可以通过weakself的手段解决。

  另一方面,它会延长对象的生命周期

3、block在离散型场景下不符合使用规范

网络请求中用delegate还是block的选型有一条严格的规范:

当回调之后要做的任务在每次回调时都是一致的情况下,选择delegate,

在回调之后要做的任务在每次回调是无法保证一致,选择block。

在离散型的调用场景下,每一次回调都是能够保证任务一致的,因此适用delegate。这也是苹果原生的网络调用也采用delegate的原因,因为苹果也是基于离散型模型去设计网络调用的。

在集约型调用的场景下,使用block是合理的,因为每次请求的类型都不一样,那么自然回调要做的任务也都会不一样,因此采用block.AFNetworking就是属于集约型的调用。

思考:为什么block无法做到回调方法的统一。

网络层在网络请求和接受请求的地方,使用block是没有问题的。但是在获得数据交付给业务方时,最好还是通过Delegate去通知到业务方。

因为Block所包含的回调代码跟调用逻辑放在同一个地方,会导致那部分代码变得很长,因为这里包括了调用前和调用后的逻辑。从另一个角度说,这在一定程度上违背了single Function, single task的原则。应该是在需要调用API的地方,就只写API调用相关的代码,在回调的地方,写回调的代码。

可通过以下方式,使得Block的回调着陆点归于统一。

[AFNetworkingAPI callApiWithParam:self.param successed:^(Response *response){
        if ([self.delegate respondsToSelector:@selector(successWithResponse:)]) {
            [self.delegate successedWithResponse:response];
        }
    } failed:^(Request *request, NSError *error){
        if ([self.delegate respondsToSelector:@selector(failedWithResponse:)]) {
            [self.delegate failedWithRequest:request error:error];
        }
    }];

 所以,要尽可能的通过Delegate的回调方式交付数据。这样可以避免不必要的跨层访问,当出现需要跨层访问的需求时(如信号切换,wifi->4g,4g->断网),通过Notification向监听网络变化的业务层发送信号。

原文地址:https://www.cnblogs.com/wjw-blog/p/9166439.html