我是块的忠实粉丝,但没有将它们用于并发。经过一番谷歌搜索,我拼凑出这个想法,将我学到的所有东西都隐藏在一个地方。目标是在后台执行一个块,完成后,执行另一个块(如 UIView 动画)...
- (NSOperation *)executeBlock:(void (^)(void))block completion:(void (^)(BOOL finished))completion {
NSOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:block];
NSOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{
completion(blockOperation.isFinished);
}];
[completionOperation addDependency:blockOperation];
[[NSOperationQueue mainQueue] addOperation:completionOperation];
NSOperationQueue *backgroundOperationQueue = [[NSOperationQueue alloc] init];
[backgroundOperationQueue addOperation:blockOperation];
return blockOperation;
}
- (void)testIt {
NSMutableString *string = [NSMutableString stringWithString:@"tea"];
NSString *otherString = @"for";
NSOperation *operation = [self executeBlock:^{
NSString *yetAnother = @"two";
[string appendFormat:@" %@ %@", otherString, yetAnother];
} completion:^(BOOL finished) {
// this logs "tea for two"
NSLog(@"%@", string);
}];
NSLog(@"keep this operation so we can cancel it: %@", operation);
}
我的问题是:
- 当我运行它时它可以工作,但我错过了什么......隐藏的地雷吗?我还没有测试过取消(因为我还没有发明一个长操作),但这看起来会起作用吗?
- 我担心我需要限定我的 backgroundOperation 声明,以便我可以在完成块中引用它。编译器没有抱怨,但是那里潜伏着一个保留循环吗?
- 如果“字符串”是一个 ivar,如果我在块运行时观察到它的键值会发生什么?或者在主线程上设置一个计时器并定期记录它?我能看到进步吗?我会宣布它是原子的吗?
- 如果这按我的预期工作,那么它似乎是隐藏所有细节并获得并发的好方法。为什么 Apple 不为我写这个?我错过了什么重要的东西吗?
谢谢。