Ручное сохранение с ARC - PullRequest
       38

Ручное сохранение с ARC

24 голосов
/ 17 октября 2011

До ARC у меня был следующий код, который сохраняет делегат во время выполнения асинхронной операции:

- (void)startAsyncWork
{
    [_delegate retain];
    // calls executeAsyncWork asynchronously
}

- (void)executeAsyncWork
{
    // when finished, calls stopAsyncWork
}

- (void)stopAsyncWork
{
    [_delegate release];
}

Что эквивалентно этому шаблону с ARC?

Ответы [ 3 ]

31 голосов
/ 29 марта 2013

Мне иногда приходилось вручную сохранять и выпускать вещи (иногда только для отладки) и придумал следующие макросы:

#define AntiARCRetain(...) void *retainedThing = (__bridge_retained void *)__VA_ARGS__; retainedThing = retainedThing
#define AntiARCRelease(...) void *retainedThing = (__bridge void *) __VA_ARGS__; id unretainedThing = (__bridge_transfer id)retainedThing; unretainedThing = nil

Это работает с использованием __bridge_retained и __bridge_transfer для приведения вещей в и из(void *), который заставляет вещи сохраняться или создавать сильную ссылку без вызова retain.

Веселитесь, но будьте осторожны!

10 голосов
/ 17 октября 2011

Почему бы просто не назначить объект-делегат сильному ивару на время выполнения асинхронной задачи?

Или иметь локальную переменную в executeAsyncWork

- (void)executeAsyncWork
{
    id localCopy = _delegate;

    if (localCopy != nil) // since this method is async, the delegate might have gone
    {
        // do work on local copy
    }
}
3 голосов
/ 17 октября 2011

Примерно так:

- (void)startAsyncWork
{
    id<YourProtocol> delegate = _delegate;
    dispatch_async(/* some queue */, ^{
        // do work
        [delegate doSomething];
    }
}

Блок будет сохранять делегата столько времени, сколько потребуется ...

...