Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have several years of experience in Obj-c and Cocoa, but am just now getting back into it and the advances of Obj-C 2.0 etc.

I'm trying to get my head around the modern runtime and declaring properties, etc. One thing that confuses me a bit is the ability in the modern runtime to have the iVars created implicitly. And of course this implies that in your code you should always be using self.property to access the value.

However, in init* and dealloc(assuming you're not using GC) methods we should be using the iVar directly (in the current runtime).

So questions are:

  1. Should we use property accessors in init* and dealloc with Modern Runtime?

  2. If so, why is this different? Is it just because the compiler can't see the iVar?

  3. If I need to override an accessor, can I still access that iVar that will be defined at runtime or do I have to define an actual iVar that the runtime will then use?

  4. Again, if I can access the synthesized iVar, why can't I continue to do this for the init* and dealloc methods?

I read the docs several times, but they seemed a bit vague about all of this and I want to be sure that I understand it well in order to decide how I want to continue coding.

Hope that my questions are clear.


Quick summary of testing:

  1. If you don't declare the ivar in legacy, compiler is completely unhappy

  2. If you use #ifndef __OBJC2__ around ivar in legacy compiler is happy and you can use both ivar directly and as property

  3. In modern runtime, you can leave the ivar undefined and access as property

  4. In modern runtime, trying to access ivar directly without declaration gives error during compile

  5. @private declaration of ivar, of course, allows direct access to ivar, in both legacy and modern

Doesn't really give a clean way to go forward right now does it?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
432 views
Welcome To Ask or Share your Answers For Others

1 Answer

In the current (OS X 10.5/GCC 4.0.1) compiler, you cannot directly access the runtime-synthesized ivars. Greg Parker, one of the OS X runtime engineers put it this way on the cocoa-dev list (March 12, 2009):

You can't in the current compiler. A future compiler should fix that. Use explicit @private ivars in the meantime. An @private ivar should not be considered part of the contract - that's what @private means, enforced by compiler warnings and linker errors.

And why isn't there a way to explicitly declare instance variables in the .m file for the new runtime?

Three reasons: (1) there are some non-trivial design details to work out, (2) compiler-engineer-hours are limited, and (3) @private ivars are generally good enough.

So, for now you must use dot-notation to access properties, even in init and dealloc. This goes against the best practice of using ivars directly in these cases, but there's no way around it. I find that the ease of using runtime-synthesized ivars (and the performance benefits) outweigh this in most cases. Where you do need to access the ivar directly, you can use a @private ivar as Greg Parker suggests (there's nothing that prevents you from mixing explicitly declared and runtime-synthesized ivars).

Update With OS X 10.6, the 64-bit runtime does allow direct access to the synthesized ivars via self->ivar.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...