Reputation: 3018
In a class interface I define some ivar
@property (strong,nonatomic) id < Protocol > initEst; // Initial estimate
This compiles without a problem but when I run the program it crashes with EXC_BAD_ACCESS and [Object .cxx_destruct] indicated by the debugger as the reason.
What is going on?
Upvotes: 0
Views: 174
Reputation: 3018
I have tested this some more and there seems to be three conditions for this particular quirk to show up.
In my particular case the ivar's Protocol
was also the same as that of the containing class. This seems to be an additional requirement for this problem to surface (refering here to my earlier answer that did not mention this).
So to elaborate on my earlier answer. If
initXXX
is an ivarid
typeProtocol
that is the same as the containing classthen the Objective-C + ARC compiler will happily compile the code but be unable to execute it.
Here is a sample of the code I used to test
@interface Dog : NSObject < Animal >
@property (nonatomic,strong) id < Animal > initState;
@end
Something like this will cause problems simply because the name starts with init. Change the name and all problems disappear.
For reference, the runtime error this generates is
Dog object overreleased while already deallocating
This snippet is pretty abstract but this may bite you in places where you need to specify some initial condition and where it is natural to name some ivar initXxx
but beware, if you use Objective-C you do not have that luxury nor will the compiler warn you that it is wrong.
The original error seemed memory allocation related and caused me to suspect the way I used the autoreleasepool but now I am fairly convinced this has nothing to do with the issue.
Upvotes: 1
Reputation: 535557
It's all about the rules of ARC automatic memory management. An initializer has special rules for how it treats the returned value: it retains and returns. See https://clang.llvm.org/docs/AutomaticReferenceCounting.html#semantics-of-init.
Objective-C in general, and ARC in particular, have some pretty strict rules about what names of methods mean. initXXX
means "this is an initializer". If this isn't an initializer, don't use the init
prefix.
You could turn off ARC entirely and manage memory yourself, but it's easier just to obey the conventions, and it fits better in case of interaction with other languages (such as Swift).
Upvotes: 1