iOS 转换异步block为同步方式运行

在iOS5以后,许多API将只提供block版本,所以调用这些API就总是以异步方式运行的了。但有时候我们不想使用异步方式,例如我们想要调用函数后立刻获取结果值的时候。

在旧的方式中,我们无法使用NSCondition做这件事:


__block NSCondition *condition = [[NSCondition alloc] init];

__block ALAssetsGroup *ret = nil;

ALAssetsLibraryGroupsEnumerationResultsBlock listGroupBlock = ^(ALAssetsGroup *group, BOOL *stop) {

[condition lock];

ret = group;

[condition signal];

[condition unlock];

};

ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError *error) {

[condition lock];

ret = nil;

[condition signal];

[condition unlock];

};

NSUInteger groupTypes = ALAssetsGroupSavedPhotos;

[self.assetsLibrary enumerateGroupsWithTypes:groupTypes usingBlock:listGroupBlock failureBlock:failureBlock];

[condition lock];

[condition wait];

[condition unlock];

return ret;

我们在block的结尾处等待一个信号量。

更简单的办法是使用dispatch_semaphore_t:


dispatch_semaphore_t sema = dispatch_semaphore_create(0);  //创建信号量

__block ALAssetsGroup *ret = nil;

ALAssetsLibraryGroupsEnumerationResultsBlock listGroupBlock = ^(ALAssetsGroup *group, BOOL *stop) {

ret = group;

dispatch_semaphore_signal(sema);  //关键点,在此发送信号量

};

ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError *error) {

ret = nil;

dispatch_semaphore_signal(sema);  //关键点,失败时发送

};

NSUInteger groupTypes = ALAssetsGroupSavedPhotos;

[self.assetsLibrary enumerateGroupsWithTypes:groupTypes usingBlock:listGroupBlock failureBlock:failureBlock];

dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);  //关键点,在此等待信号量

return ret;

你可能感兴趣的:(iOS 转换异步block为同步方式运行)