__blocks并在dispatch_sync中分配对象

时间:2011-01-10 20:58:51

标签: iphone objective-c grand-central-dispatch

我想返回一个数组,其内容是在dispatch_sync块中设置的。

我通常看到的代码是这样的:

-(NSArray *)getSomeLockedList {

    __block NSArray *resultList;

    dispatch_sync(myQueue, ^{   
       // copy contents of my ivar NSMutableArray into return variable  
       resultList = [ivarContentList copy]; 
    });

    // add auto-release since a 'copy' was done within block
    return [resultList autorelease]; 
}

如果我没有复制一个完整的数组,而是想逐个添加,我可以跳过返回值的'autorelease'吗?

-(NSArray *)getSomeLockedList {

    __block NSArray *someResultKeys; // is it ever safe to do the alloc here?

    dispatch_sync(myQueue, ^{       
       someResultKeys = [NSMutableArray array];

    for (id entry in ivarContentList) {

          // do some work on entry instance
          [someResultKeys addObject:entry];     
       }        
    });

    return someResultKeys; // autorelease not necessary?
}

[NSMutableArray数组]分配在dispatch_sync块中是否安全,以便在完成此方法的堆栈后继续使用结果?

2 个答案:

答案 0 :(得分:3)

不,这不安全。问题是,当您调度到队列时,当该队列的NSAutoreleasePool耗尽时,将收集在该队列上自动释放的任何对象。你无法控制这个时间。考虑这一点的适当方法是始终假设自动释放池将在块完成队列执行时消耗。

在您的情况下处理此问题的正确方法是使用

someResultKeys = [[NSMutableArray alloc] init];

在队列中,然后在dispatch_sync之后调用[someResultKeys autorelease]

答案 1 :(得分:0)

只需编写

,就可以更轻松地避免使用__block变量
NSMutableArray* someResultKeys = [NSMutableArray array];

在街区之外。但是,我想知道dispatch_sync。你知道dispatch_sync会等到块完成执行吗? (并且在串行队列的情况下,这意味着在它完成执行之前的所有块)。你有没有理由不直接调用代码?