Подтвердить что ты не робот

Ручное сохранение с помощью ARC

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

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

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

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

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

4b9b3361

Ответ 1

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

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

- (void)executeAsyncWork
{
    id localCopy = _delegate;

    if (localCopy != nil) // since this method is async, the delegate might have gone
    {
        // do work on local copy
    }
}

Ответ 2

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

#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 *), которые заставляют вещи быть сохранены, или для создания сильной ссылки без вызова сохранения.

Удачи, но будьте осторожны!

Ответ 3

Что-то вроде этого:

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

Блок сохранит делегат до тех пор, пока это необходимо...