skaak
skaak

Reputation: 3018

Objective-C init quirks

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

Answers (2)

skaak
skaak

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

  1. initXXX is an ivar
  2. of id type
  3. that implements a Protocol that is the same as the containing class

then 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

matt
matt

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

Related Questions