Objective-C块和变量

时间:2012-10-12 16:48:19

标签: objective-c variables objective-c-blocks

我今天开始使用Objective-C块。我写了以下代码:

NSArray *array = @[@25, @"abc", @7.2];

void (^print)(NSUInteger index) = ^(NSUInteger index)
{
    NSLog(@"%@", array[index]);
};

for (int n = 0; n < 3; n++)
    print(n);

哪个正常。我需要在声明后更改array变量,所以我尝试使用以下代码:

NSArray *array;

void (^print)(NSUInteger index) = ^(NSUInteger index)
{
    NSLog(@"%@", array[index]);
};

array = @[@25, @"abc", @7.2];

for (int n = 0; n < 3; n++)
    print(n);

然而,这不起作用。控制台只打印(null)三次。为什么这不起作用,虽然它确实适用于我的第一段代码?

2 个答案:

答案 0 :(得分:20)

这是因为块在创建块时按值和捕获变量(除非您使用__block)。

你可能想要的是:

NSArray *array = @[@25, @"abc", @7.2];

void (^print)(NSUInteger index) = ^(NSUInteger index)
{
    NSLog(@"%@", array[index]);
};

for (int n = 0; n < 3; n++)
    print(n);

__block的示例:

__block NSArray *array;

void (^print)(NSUInteger index) = ^(NSUInteger index)
{
    NSLog(@"%@", array[index]);
};

array = @[@25, @"abc", @7.2];

for (int n = 0; n < 3; n++)
    print(n);

请注意,如果您实际上不需要修改块内的变量并将其反射到外部,那么使用__block的效率会低一些。

答案 1 :(得分:3)

该块在创建时捕获array指针。您可以添加__block修饰符以使块通过引用捕获指针,但这通常很昂贵,不建议使用。最好在数据准备好在块内使用后创建捕获块。