我今天开始使用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)
三次。为什么这不起作用,虽然它确实适用于我的第一段代码?
答案 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
修饰符以使块通过引用捕获指针,但这通常很昂贵,不建议使用。最好在数据准备好在块内使用后创建捕获块。