Ios 在快速枚举的for循环中使用块的bug
因此,我试图在数组中建立一个块队列,然后在稍后的阶段执行该队列,该队列在forloop中建立,该forloop使用块中使用的字符串枚举Ios 在快速枚举的for循环中使用块的bug,ios,objective-c,objective-c-blocks,Ios,Objective C,Objective C Blocks,因此,我试图在数组中建立一个块队列,然后在稍后的阶段执行该队列,该队列在forloop中建立,该forloop使用块中使用的字符串枚举 NSArray *array = @[@"test", @"if", @"this", @"works"]; NSMutableArray *queue = [NSMutableArray new]; for(id key in array){ //add the work to the queue void (^ request)() =
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
}
块是否不适用于for循环中的枚举对象(如果没有在同一个for循环中执行),或者这看起来像是一个bug?更改
[queue addObject:request];
到
更新:
块在堆栈中创建。因此,
request
是一个局部变量。当您将其添加到NSMUTABLEARRY时,它将被保留,但这对于块来说是不够的!当您离开{}
时,块仍将被删除-它是否保留并不重要。您应该先将其复制到heap,然后再保留(通过添加到数组)。应该注意的是,初始代码不会复制堆栈goodies(表示块中使用的所有变量),而第二个代码会复制,因此您的块都引用了某个addr,该addr碰巧是@“works”@DanZimm,实际上块复制了键,它只是停留在堆栈上。需要复制消息才能将其从堆栈移动到堆。它打印工作
,只是因为他足够幸运,块的最后一个实例在堆栈上仍然完好无损,可以执行。@JasonCoco当我说“复制堆栈货物”时,我的意思是复制到堆中;P@avt-这肯定会泄漏块,因为copy
返回一个拥有的块,而addObject:
会再次保留它吗?缺少release
或autorelease
?@avt-可能我不清楚,复制的块肯定会保留两次,并且会泄漏。原来的堆栈块不会泄漏。打开ARC,这不会发生。是的,我们正在将应用程序转换为ARC,但这是一个整体项目,所以不是那么容易呵呵。不过,我应该在问题中提到这一点,我的bad@JoshCaswell:“这不会发生。”从我对ARC规范的阅读来看,这并不能保证。
[queue addObject:[request copy]];