开发者

Manual retain with ARC

Before ARC I had the following code that retains the开发者_运维百科 delegate while an async operation is in progress:

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

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

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

What is the equivalent to this pattern with ARC?


I have occasionally needed to manually retain and release things (sometimes just for debugging) and came up with the following macros:

#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

This works by using the __bridge_retained and __bridge_transfer to cast things to and from (void *) which causes things to be retained, or to create a strong reference without calling retain.

Have fun, but be careful!


Why not just assign your delegate object to a strong ivar for the duration of the asynchronous task?

Or have a local variable in executeAsyncWork

- (void)executeAsyncWork
{
    id localCopy = _delegate;

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


Something like this:

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

The block will retain the delegate as long as needed...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜