有一天我很想写这样的代码......
- (void)myMainMethod {
[self doSomethingWithCompletion:^{
NSLog(@"My original completion block");
}];
}
- (void)doSomethingWithCompletion:(CompletionBlock)completion {
if (self.someBoolValue) {
completion = ^{
NSLog(@"My wrapper completion block");
if (completion) completion();
};
}
[self someMethodThatTakesACompletion:completion];
}
- (void)someMethodThatTakesACompletion:(CompletionBlock)completion {
if (completion) completion();
}
它似乎工作正常,但我不能100%确定它是否安全。创建一个新块以包装旧块总是一个选项,但我的一部分赞赏这种方法的简单性。
我特别好奇,这甚至可以起作用。
顺便说一下,这段代码的输出是......
My wrapper completion block
My original completion block
答案 0 :(得分:2)
有两个completion
变量:
方法参数,是常规局部变量。我们称之为“外部完成”。
块内部的变量,它本质上是块对象的实例变量。我们称之为“内部完成”。
它起作用,因为这两个变量彼此完全分开。
创建块时,将为内部完成分配外部完成的值。创建块后,将外部完成分配给新值。这不会影响内部完工的价值。
它与此基本相同:
NSString* foo = @"there.";
foo = [NSString stringWithFormat:@"Hello %@", foo];
请注意,如果将completion
声明为__block
变量,则无效。在这种情况下,更改外部完工的价值将影响内部完工的价值。