Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can an Objective-C object be deallocated while an instance method is being invoked on it?

Consider the following: An instance of an Objective-C class is referenced by one strong reference and one weak reference (under ARC). On thread X, a method is called on the instance via the weak reference. On thread Y, the strong reference is broken such that there are no more strong references to the instance, and it should be deallocated.

Is this situation possible, in that the object might be deallocated on thread Y while the method is executing on thread X? Similarly, does invoking a method on an object 'retain' that object until the method returns?

like image 411
Andrew Hershberger Avatar asked Dec 06 '12 04:12

Andrew Hershberger


1 Answers

ARC actually does retain weak references before calling instance methods on them, and releases after the call.

I was researching this issue and was corrected by a colleague after showing him this stackoverflow question. He pointed to this: http://lists.apple.com/archives/objc-language/2012/Aug/msg00027.html

Sure enough, in the assembly, ARC retains and releases around an invocation on a weak reference.

One time you will want to listen to CLANG_WARN_OBJC_RECEIVER_WEAK is for nil checks, when nil could cause an error.

if (self.weakRefToParent) {
    //self.weakRefToParent could be dealloced and set to nil at this line
    NSString *name = [self.weakRefToParent name]; //CLANG_WARN_OBJC_RECEIVER_WEAK warning
    [self.namesArray addObject:name];  //name is nil, NSInvalidArgumentException
}

This is the safer way:

Parent *strongRefToParent = self.weakRefToParent;
if (strongRefToParent) {
    NSString *name = [strongRefToParent name];
    [self.namesArray addObject:name];
}
like image 130
James Mitchell Avatar answered Sep 22 '22 18:09

James Mitchell