Objective-C 版本的 lambda 或者 closur

2016-05-19  本文已影响120人  cbd0bfba9942

使用 block 定义异步接口:

```

- (void)downloadObjectsAtPath:(NSString *)path

completion:(void(^)(NSArray *objects, NSError *error))completion;

```

当你定义一个类似上面的接口的时候,尽量使用一个单独的 block 作为接口的最后一个参数。把需要提供的数据和错误信息整合到一个单独 block 中,比分别提供成功和失败的 block 要好。

以下是你应该这样做的原因:

通常这成功处理和失败处理会共享一些代码(比如让一个进度条或者提示消失);

Apple 也是这样做的,与平台一致能够带来一些潜在的好处;

block 通常会有多行代码,如果不作为最后一个参数放在后面的话,会打破调用点;

使用多个 block 作为参数可能会让调用看起来显得很笨拙,并且增加了复杂性。

看上面的方法,完成处理的 block 的参数很常见:第一个参数是调用者希望获取的数据,第二个是错误相关的信息。这里需要遵循以下两点:

若 objects 不为 nil,则 error 必须为 nil

若 objects 为 nil,则 error 必须不为 nil

因为调用者更关心的是实际的数据,就像这样:

```

- (void)downloadObjectsAtPath:(NSString *)path

completion:(void(^)(NSArray *objects, NSError *error))completion {

if (objects) {

// do something with the data

}

else {

// some error occurred, 'error' variable should not be nil by contract

}

}

```

此外,Apple 提供的一些同步接口在成功状态下向 error 参数(如果非 NULL) 写入了垃圾值,所以检查 error 的值可能出现问题。

上一篇下一篇

猜你喜欢

热点阅读