使用快速枚举的for循环中的块的错误

Fon*_*nix 2 objective-c ios objective-c-blocks

因此,我尝试在数组中构建块队列,然后在稍后阶段执行队列,队列在使用块中使用的字符串枚举的forloop中构建.

NSArray *array = @[@"test", @"if", @"this", @"works"];
NSMutableArray *queue = [NSMutableArray new];

for(id key in array){

    //add the work to the queue
    void (^ request)() = ^{
        NSLog(@"%@", key);
    };

    [queue addObject:request];
    //request(); //this works fine if i just execute the block here, all the strings are printed
}

for(id block in queue){

    void (^ request)() = block;

    request(); //this just prints 'works' multiple times instead of all the other strings
}
Run Code Online (Sandbox Code Playgroud)

do块在for循环中不能使用枚举对象(当不在同一个for循环中执行时),或者这看起来像一个bug?

Avt*_*Avt 5

更改

[queue addObject:request];
Run Code Online (Sandbox Code Playgroud)

[queue addObject:[request copy]];
Run Code Online (Sandbox Code Playgroud)

更新:块在堆栈中创建.request局部变量也是如此.当你将它添加到NSMutableArray时,它会被保留,但对于块来说还不够!当你离开时,无论如何都会删除阻止{}- 无论是否保留都无关紧要.您应该先将其复制到堆中,然后保留(通过添加到数组中).

  • 应该注意的是,初始代码不会复制堆栈的好东西(意味着你在块中使用的所有变量),而第二个代码就是这样,因此你的块都引用了一些碰巧是@"工作"的addr (2认同)
  • @DanZimm实际上块确实复制了密钥,它只是停留在堆栈上.需要复制消息才能将其从堆栈移动到堆中.它打印`works`只是因为他很幸运,块的最后一个实例在堆栈上仍然完好无损并且可以执行. (2认同)