在init和dealloc方法中有效使用访问器?
我已经从几个来源(stackoverflow.com,cocoa-dev,文档,博客等)了解到,在init和dealloc方法中使用访问器和设置(foo,setFoo :)是“错误的”。 我明白,如果你这样做的话,有一个遥远的可能性混淆了观察财产的其他物体。 ( 这里给出一个简单的例子)
不过,我不得不说,我不同意这种做法,原因如下:
新的Objective-C运行时(iPhone上的那个和10.5中的64位运行时)允许您声明属性而不声明相应的ivar。 例如,下面的类将在10.5或iPhone(设备,而不是模拟器)上编译得很好:
@interface Foo : NSObject { } @property (retain) id someObject; @end @implementation Foo @synthesize someObject; @end
理解上面是一个完全有效的Objective-C类,比方说,我决定编写一个初始化程序,并为了内存pipe理的目的,使用dealloc方法(因为GC在iPhone上不可用)。 我读过的关于初始化和释放的所有东西都会导致我写下面两个方法:
- (id) init { if (self = [super init]) { //initialize the value of someObject to nil [self setSomeObject:nil]; } return self; } - (void) dealloc { //setting someObject to nil will release the previous value [self setSomeObject:nil]; [super dealloc]; }
但是,根据文件和民意,这是“错误的”。 所以我的问题是这样的:
- 我怎样才能不使用访问器初始化someObject? 您可能会说,编译器(或运行时或任何)将确保someObject已被设置为零,但我相信这是不正确的行为依靠。 在C中有一个体面的背景,由于没有正确初始化variables,我看到了相当多的错误,这似乎有点不同。
- 如果我不应该在dealloc方法中使用访问器,我怎么能释放someObject?
如果对这两者之一的答案是“你不能”,那么在init和dealloc方法中使用访问器又怎么样?
据我所知,苹果公司认为目前的10.5行为是不能直接访问的行为, 你应该可以直接访问它,但不能。
因此,你应该能够做到:
someObject = nil;
代替
self.someObject = nil;
与此同时,直接使用访问者是在没有提供明确的ivar的情况下完成的唯一方法。
更新 :这个bug已经修复; 你现在可以做someObject = nil
就好了。
编辑(2013年2月13日):正如我在下面的评论中指出的那样,特别是自ARC以来,我已经改变了我的想法。 在ARC之前,我看到了很多由于init
ivar分配不正确而导致崩溃的错误。 国际海事组织,特别是与初级团队合作,初次使用访问器时遇到的罕见问题远远超过了伊娃访问的常见错误。 由于ARC已经消除了这些types的bug,所以在init
中使用accessor的可能性很小,所以我更换了init
和dealloc
的ivars,并且只能在那些地方; 其他地方的访问器是可能的(显然你不能在访问器本身内部使用访问器)
PRE-ARC答案
我坚决不同意那些反对访问者的人。 在几乎所有的情况下,这都是一个使用访问器的好地方,它节省了我在新的Cocoa编码器中看到的许多错误,这些错误在指定in -init
时总是无法保留。
-dealloc
是一个更强硬的电话。 我有一个天然的倾向,使用accessor那里(以便他们在任何地方使用),但它可能会导致头痛由于KVO(甚至NSNotifications,如果您发布更改通知在您的setter)。 这就是说,虽然我没有在-dealloc
使用访问器, -dealloc
我认为它非常值得商榷,而且苹果公司对此非常不一致(我们知道他们正在调用setView:
在UIViewController的-dealloc
中)。
无论如何,我会说使用不足的访问者已经造成了100倍的过度使用的错误。 除非有强烈的理由,否则我总是会错误地使用它们。