8

我今天开始使用 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)三遍。为什么这不起作用,而它确实适用于我的第一段代码?

4

2 回答 2

21

这是因为块按值创建块的时间捕获变量(除非您使用__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请注意,如果您实际上不需要修改块内的变量并将其反映在外部,则使用它的效率会降低一些。

于 2012-10-12T16:50:27.980 回答
3

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

于 2012-10-12T16:53:13.137 回答