《Effective Objective-C 2.0》这本书中第 39 条:用 handler 块降低代码分散程度,建议“使用同一个块来处理成功与失败情况”,在实习的阶段刚好遇到这个情况,所以浅显的论述一下自己的观点,希望能有个抛砖引玉的效果。
本书中对两种回调处理的分析
成功情况和失败情况用两个块分别处理
API 如下:
EOCNetworkFetcher *fetcher = [[EOCNetworkFetcher alloc] initWithURL:url]; [fetcher startWithCompletionHander:^(NSData *data) { // Handler success } failureHandler:^(NSError *error) { // Handler failure }];
优点:
- 不同情况分开写,代码更易读懂
- 还可以根据具体需要,把处理失败情况或者成功情况所用的代码省略
成功情况和失败情况处理全部放在一个块
API 如下:
EOCNetworkFetcher *fetcher = [[EOCNetworkFetcher alloc] initWithURL:url]; [fetcher startWithCompletionHander:^(NSData *data, NSError *error) { if (error) { // Handle failure } else { // Handle success } }];
优点:
- 在传入错误信息时,可以把数据也传进来
- 可以根据问题作适当处理,并利用已经获得的数据做些事情
- 调用 API 的代码可能会在处理成功响应的过程中发现错误
根据自己的具体使用经验来分析我为什么推荐前者:
分离网络请求成功和失败处理
先给出我司在网络请求回调的处理方式(大概如下):
^(DQKDataModel *dataModel, DQKErrorModel *errorModel, NSError *error) { // Handle … }
Response 的 JSON 数据大概如下:
{ data = { topic = “天气不错”; }; respcd = “00”; respmsg = “数据获取成功”; }
回调的代码块就是上面的样子,分别是成功返回数据信息(data)、业务逻辑信息(respcd ,respmsg)、网络请求错误信息。一个代码块,数据可以统一处理。
我们一般不会去在 GET POST 中,获得很大的数据的 Response ,所以作者提到的这种数据一半就没了的情况基本是不会有的,我们从 业务处理 和 网络处理 两个情况来分析。
这里业务逻辑信息是指如登录密码错误,没有权限发帖等逻辑。
从网络请求层面分析,如果网络有问题,或者服务器处理出现错误等等,这个时候可能会出现错误 404 ,500 之类的情况,此时就不会有 JSON 数据的返回,那也就不会有返回数据信息,业务逻辑信息,因为这两个是同时在 JSON 中一起返回的。网络回调的层次应该如下所示:
成功返回数据信息 | 业务逻辑信息 |
|
二者并没有什么可联系的关系,有数据一般就没有网络错误信息,没有数据一般就没有网络错误信息。
执行成功的代码就必定不执行失败的代码,反之亦然
两个块的时候,一个块专注处理成功情况,一个块专注网络错误,不需要再去判断有那个数据,没有那个数据,会处理成功的代码块就一定是有数据的,会处理错误信息的代码就一定是网络请求中出现了某些问题。
同时这里还减少了一层 鞭尸金字塔 ,更方便代码的维护和 Review 。
这里说的鞭尸金字塔就是类似如下代码:
if (condition) { if (condition) { if (condition) { if (condition) { statements } else if (expression) { statements } else { statements } } } else if (expression) { statements } else { statements } } else { statements }
## 业务失败放在数据中 那么我们该怎么解决这种既需要处理网络请求错误,也需要处理业务逻辑错误呢? 我的方法如下: ```Objective-C ^(DQKDataModel *dataModel) { if (dataModel.error) { // Handler data error } else if (dataModel.data) { // Handler data } } failureHandler:^(NSError *error) { // Handler failure }
对返回的数据处理生成两个属性,一个是业务错误信息,一个是数据成功信息,相比之前的处理可能会清晰一点。
如果您对网络请求的封装的有更好的想法、理解,欢迎大家一起微博上讨论(暂未开通博客评论功能,见谅见谅)。