Блоки, Штабеля И Кучи


Используя Xcode 4.2 и ARC, я написал следующий код, прежде чем понял, как блоки должны быть скопированы из стека в кучу.

-(void) downloadWithBlock:(void (^)(void))callbackBlock;
{
    // start the data download in the background...
    NSOperation *backgroundOperation = [NSBlockOperation blockOperationWithBlock:^{
        // synchronous download code
    }];
    [backgroundOperationQueue addOperation:backgroundOperation];
    NSOperation *foregroundOperation = [NSBlockOperation blockOperationWithBlock:^{
        callbackBlock();
    }];
    [foregroundOperation addDependency:backgroundOperation];
    [[NSOperationQueue mainQueue] addOperation:foregroundOperation];    
}
Код работает, но я не доверяю ему, потому что не понимаю его. В другом разделе кода я столкнулся с сбоями приложений при вызове блоков, которые хранились в ivars без использования-copy. Это заставило меня задуматься, стоит ли переписывать этот раздел кода следующим образом:
-(void) downloadWithBlock:(void (^)(void))callbackBlock;
{
    void(^heapBlock)(void) = [callbackBlock copy];    
    // start the data download in the background...
    NSOperation *backgroundOperation = [NSBlockOperation blockOperationWithBlock:^{
        // synchronous download code
    }];
    [backgroundOperationQueue addOperation:backgroundOperation];
    NSOperation *foregroundOperation = [NSBlockOperation blockOperationWithBlock:^{
        heapBlock();
    }];
    [foregroundOperation addDependency:backgroundOperation];
    [[NSOperationQueue mainQueue] addOperation:foregroundOperation];    
}

Моя единственная забота здесь чтобы лучше понять, как работают указатели блоков. Является ли любой из этих разделов кода приемлемым? Вызывает ли вызов блока внутри другого блока компилятор для вставки скрытой операции Block_copy?

1 4

1 ответ:

Не только вызов блока внутри блока, но и любая прямая ссылка на него вызовет копию. Включая передачу его в качестве аргумента для чего-то еще. То же самое касается типов ObjC в блоке (за исключением того, что это простое сохранение, а не копия для них).