Reputation: 4463
I had a library designed for ARC and iOS 5, but a customer wanted to build for iOS 4.x. I converted properties with the weak
qualifer to unsafe_unretained
, however now it seems I am running into memory corruption-esq crashes.
In the case of the crash, I have a delegate property like this
@property (unsafe_unretained) id<MYDelegateProtocol> delegate;
and I @synthesize
the ivar.
whenever I want to call a method on the delegate, I check if it is nil
, and if it is not, then I call the method, since I have no optional methods in that protocol, I don't check respondsToSelector
.
However, since changing the weak
to unsafe_unretained
, I have found that apparently the reference goes away, and I am left with a dangling pointer. If I put a breakpoint on ObjC Exceptions, (for unrecognized message), and then po
the address of the object, I see that it is an object that is not even implementing the protocol of the delegate, so of course it crashes.
When using unsafe_unretained
how can I know that the reference has "gone away"? My code relied on the pointer being zeroed out before.
Upvotes: 1
Views: 496
Reputation: 4452
You have an object ownership problem. An object that has been released won't be nil, it would just be pointing at the address where the object used to be. An nil pointer would point to 0x0. You need to analyze how come your architecture has a delegate that is being released while the record being delegated is alive. On some special circumstances, objects being delegated might retain their delegates (like NSURLConnection). On other cases, objects being delegated are a property of their delegates, in which case, the delegation needs to be cleared out before deallocation. Analyze your pattern and/or provide more information.
Upvotes: 2
Reputation: 18363
When using unsafe_unretained how can I know that the reference has "gone away"? My code relied on the pointer being zeroed out before.
This has to be determined at compile time by you. Often, the object that is the delegate should set the delegate
property of the object delegating to it to nil
in the dealloc
method. For example:
- (void)dealloc
{
if (_httpRequest.delegate == self)
_httpRequest.delegate = nil;
}
Hope this helps!
Upvotes: 1