__блокирует и выделяет объекты в dispatch_sync - PullRequest
1 голос
/ 10 января 2011

Я хотел бы вернуть массив, содержимое которого было установлено во время блока 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 array] в блоке dispatch_sync для дальнейшего использования результата после завершения стека для этого метода?

Ответы [ 2 ]

3 голосов
/ 11 января 2011

Нет, это не безопасно. Проблема заключается в том, что при отправке в очередь любые объекты, автоматически высвобождаемые в этой очереди, будут собираться при сливе NSAutoreleasePool в этой очереди. Вы не можете контролировать, когда это будет. Надлежащий способ подумать об этом - всегда предполагать, что пул автоматического выпуска истощит момент, когда ваш блок завершит выполнение в очереди.

Правильный способ справиться с этим в вашем случае - использовать

someResultKeys = [[NSMutableArray alloc] init];

в очереди, а затем вызовите [someResultKeys autorelease] после dispatch_sync.

0 голосов
/ 20 марта 2014

Это делается гораздо проще, избегая переменной __block, просто записав

NSMutableArray* someResultKeys = [NSMutableArray array];

за пределами блока.Однако мне интересно узнать о dispatch_sync.Вы знаете, что dispatch_sync будет ждать завершения выполнения блока?(И в случае последовательной очереди это также означает, что все блоки до того, как она закончила выполняться).Есть ли веская причина, почему вы не вызываете код напрямую?

...