用自己包裹一个块

时间:2014-05-25 08:36:35

标签: objective-c objective-c-blocks

有一天我很想写这样的代码......

- (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

1 个答案:

答案 0 :(得分:2)

有两个completion变量:

  • 方法参数,是常规局部变量。我们称之为“外部完成”。

  • 块内部的变量,它本质上是块对象的实例变量。我们称之为“内部完成”。

它起作用,因为这两个变量彼此完全分开。

创建块时,将为内部完成分配外部完成的值。创建块后,将外部完成分配给新值。这不会影响内部完工的价值。

它与此基本相同:

NSString* foo = @"there.";
foo = [NSString stringWithFormat:@"Hello %@", foo];

请注意,如果将completion声明为__block变量,则无效。在这种情况下,更改外部完工的价值将影响内部完工的价值。