【问题标题】:Objective-C blocks and variablesObjective-C 块和变量
【发布时间】:2012-10-12 16:48:19
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    这是因为块捕获变量按值创建块时(除非您使用__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 的效率会稍低。

    【讨论】:

    • 使用__block有什么区别?
    • __block 告诉编译器通过引用捕获变量,因此您可以在块内修改它并使新值在块外可见。 (我将添加一个带有 __block 的示例。)
    • __block 通过引用捕获变量。 编辑: 两次都被殴打。 :)
    • 谢谢,使用__block 为我做了。我实际上需要在我的块中修改我的变量,它现在可以正常工作。 :)
    • 我尝试用这段代码修改块内的变量,但打印三个空值,知道吗? __block NSMutableArray *array; void (^print)(NSUInteger index) = ^(NSUInteger index) { [array addObject:@"444"]; NSLog(@"%@", array[index]); }; [数组添加对象:@“111”]; [数组添加对象:@“222”]; [数组添加对象:@“333”]; for (int n = 0; n
    【解决方案2】:

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

    【讨论】:

    • 有意思,你有例子吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多