在现代运行时中使用实例变量
我在Obj-c和Cocoa方面有几年的经验,但现在又回到了它,还了解了Obj-C 2.0等的进步.
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.
我正在设法绕过现代运行时并声明属性等.令我有些困惑的是现代运行时隐式创建iVar的能力.当然,这意味着在您的代码中,您应该始终使用self.property来访问该值.
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.
但是,在init *和dealloc(假设您不使用GC)方法中,我们应该直接使用iVar(在当前运行时).
However, in init* and dealloc(assuming you're not using GC) methods we should be using the iVar directly (in the current runtime).
问题是:
-
我们应该在init *中使用属性访问器,并在Modern Runtime中取消分配吗?
Should we use property accessors in init* and dealloc with Modern Runtime?
如果是这样 ,为什么会有所不同?仅仅是因为编译器看不到iVar吗?
If so, why is this different? Is it just because the compiler can't see the iVar?
如果需要覆盖访问器,是否仍可以访问将在运行时定义的iVar,还是必须定义运行时将使用的实际iVar?
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?
再次, 如果我可以访问综合的iVar ,为什么我不能继续对init *和dealloc方法执行此操作?
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.
希望我的问题很清楚.
快速测试总结:
-
如果您未在旧版中声明ivar,则编译器将完全不满意
If you don't declare the ivar in legacy, compiler is completely unhappy
如果您在旧版编译器中的ivar周围使用#ifndef __OBJC2__
表示满意,则可以直接使用ivar并作为属性使用
If you use #ifndef __OBJC2__
around ivar in legacy compiler is happy and you can use both ivar directly and as property
在现代运行时中,您可以将ivar保留为未定义状态并作为属性访问
In modern runtime, you can leave the ivar undefined and access as property
在现代运行时中,尝试直接在不声明的情况下直接访问ivar会在编译期间出现错误
In modern runtime, trying to access ivar directly without declaration gives error during compile
@private
ivar声明当然可以在旧版和现代版中直接访问ivar
@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?
在当前(OS X 10.5/GCC 4.0.1)编译器中,您无法直接访问运行时综合的ivars.一位OS X运行时工程师Greg Parker称它为可可设备清单中的这种方式(2009年3月12日):
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):
您不能在当前的编译器中.一种 将来的编译器应修复该问题.使用 显式@private ivars在 与此同时. @private ivar不应该 被视为合同的一部分- 这就是@private的意思,强制执行 通过编译器警告和链接器 错误.
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.
为什么没有办法 显式声明实例变量 在新运行时的.m文件中?
And why isn't there a way to explicitly declare instance variables in the .m file for the new runtime?
三个原因:(1)有一些 不平凡的设计细节起作用 ,(2)编译器工程师小时 有限,并且(3)@private ivars是 通常足够好.
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.
因此,目前,即使在init
和dealloc
中,也必须使用点符号来访问属性.在这种情况下,这与直接使用ivars的最佳做法背道而驰,但是没有办法解决.我发现在大多数情况下,使用运行时综合的ivars的难易程度(以及性能优势)远胜于此.您确实需要直接访问ivar的地方,可以按照Greg Parker的建议使用@private ivar(没有什么可以阻止您混合显式声明的和运行时综合的ivars).
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).
更新在OS X 10.6中,64位运行时确实允许通过self->ivar
直接访问合成的ivars.
Update With OS X 10.6, the 64-bit runtime does allow direct access to the synthesized ivars via self->ivar
.