我现在从多个来源(stackoverflow.com、cocoa-dev、文档、博客等)听说,在 init 和 dealloc 方法中使用访问器和设置(foo、setFoo:) 是“错误的”。我知道如果这样做,很可能会混淆正在观察该属性的其他对象。 (给出一个简单的例子here https://stackoverflow.com/questions/192721)
不过,我不得不说,我并不认同这种做法,理由如下:
新的 Objective-C 运行时(iPhone 上的运行时和 10.5 中的 64 位运行时)允许您声明属性without声明相应的ivar。例如,以下类可以在 10.5 或 iPhone(设备,而不是模拟器)上正常编译:
@interface Foo : NSObject { }
@property (retain) id someObject;
@end
@implementation Foo
@synthesize someObject;
@end
了解上面是一个完全有效的 Objective-C 类,假设我决定编写一个初始化程序,并出于内存管理的目的,编写一个 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 已经设置为 nil,但我相信依赖它是不正确的行为。拥有良好的 C 背景,我见过相当多的由于未正确初始化变量而导致的错误,这似乎没什么不同。
- 如果我不应该在 dealloc 方法中使用访问器,如何释放 someObject?
如果其中任何一个的答案是“你不能”,那么在 init 和 dealloc 方法中使用访问器怎么会不好呢?
编辑(2013 年 2 月 13 日):正如我在下面的评论中所指出的,特别是自从添加 ARC 以来,我对此改变了主意。在 ARC 之前,我看到了很多由于 ivar 分配不正确而导致崩溃的错误init
。 IMO,特别是与初级团队合作,在中使用访问器的罕见问题init
被 ivar 访问的常见错误所抵消。由于 ARC 已经消除了这些类型的错误,因此在使用访问器时出现的罕见但可能的错误init
原因更重要,因此我转而支持直接使用 ivarsinit
and dealloc
,并且仅在那些地方;在其他可能的地方使用访问器(显然你不能在访问器本身内部使用访问器......)
预弧答案
我强烈不同意那些反对访问器的人-init
。几乎在所有情况下,这是使用访问器的一个非常好的地方,并且它可以避免我在新的 Cocoa 编码人员中看到的许多错误,这些编码人员在分配时总是无法保留-init
.
-dealloc
这是一个更艰难的决定。我自然倾向于在那里使用访问器(以便它们随处使用),但它可能会因 KVO(甚至 NSNotifications,如果您在 setter 中发布更改通知)而引起头痛。也就是说,虽然我不使用访问器-dealloc
,我认为这是非常有争议的,苹果对此非常不一致(我们知道他们正在打电话setView:
在 UIViewController 中-dealloc
例如)。
无论如何,我想说访问器使用不足所导致的错误是过度使用的错误的 100 倍。我总是会错误地使用它们,除非有充分的理由不这样做。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)