Ручное сохранение с помощью ARC
До ARC у меня был следующий код, который сохраняет делегат во время выполнения асинхронной операции:
- (void)startAsyncWork
{
[_delegate retain];
// calls executeAsyncWork asynchronously
}
- (void)executeAsyncWork
{
// when finished, calls stopAsyncWork
}
- (void)stopAsyncWork
{
[_delegate release];
}
Что эквивалентно этому шаблону с ARC?
Ответы
Ответ 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];
}
}
Блок сохранит делегат до тех пор, пока это необходимо...