Блоки, стеки и кучи - PullRequest
       6

Блоки, стеки и кучи

4 голосов
/ 14 декабря 2011

Используя 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 Ответ

1 голос
/ 14 декабря 2011

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

...