在@mmalc对this question的回答中,他指出:“通常情况下,在dealloc(或init)中不应使用访问器方法。”为什么mmalc这样说?
我能想到的唯一原因是性能和避免@dynamic setters的未知副作用。
讨论?
我能想到的唯一原因是性能和避免@dynamic setters的未知副作用。
讨论?
这基本上是一个减少漏洞可能性的指南。
在这种情况下,你的 setter/getter 可能会无意中对对象的状态做出直接或间接的假设。当对象正在被设置或销毁时,这些假设可能会成为问题。
例如,在下面的代码中,观察者不知道 'Example' 正在被销毁,可能会假设其他已经释放的属性仍然有效。
(你可以认为你的对象在拆除自身之前应该删除所有观察者,这是一个好的实践,也是另一个防止意外问题的指南)。
@implementation Example
-(void) setFoo:(Foo*)foo
{
_foo = foo;
[_observer onPropertyChange:self object:foo];
}
-(void) dealloc
{
...
self.foo = nil;
}
@end
重点在于使用习惯一致的代码。如果您适当地模式化所有代码,则有一组规则可以保证在init / dealloc中使用访问器是安全的。
最大的问题是(正如mmalc所说),设置属性默认状态的代码不应该经过访问器,因为这会导致各种各样的问题。但问题在于,init没有必要设置属性的默认状态。出于多种原因,我一直在转向使用自初始化的访问器,如下面的简单示例:
- (NSMutableDictionary *) myMutableDict {
if (!myMutableDict) {
myMutableDict = [[NSMutableDictionary alloc] init];
}
return myMutableDict;
}
这种属性初始化方式能够推迟许多可能并非必要的初始化代码。在上述示例中,init方法不需要负责对属性状态进行初始化,因此使用init方法中的访问器完全是安全的(甚至是必要的)。
值得承认的是,这确实对您的代码施加了额外的限制,例如,在超类中具有自定义访问器的子类必须调用超类的访问器,但这些限制与Cocoa中其他常见限制并没有出入。
nil
分配给该属性,因为访问器将自动创建一个新的数组实例。 - Georg Schöllyobject.x = foo
应该意味着紧接着 object.x == foo
为 YES
。如果不是的话,也许(非属性)方法会更好。 - Clay Bridges你自己回答了这个问题:
后者特别是在您的类可以被子类化时成为一个问题。
然而,不清楚为什么这特别针对于 Objective-C 2 访问器?使用声明属性或自己编写访问器同样适用这些原则。
当分配/释放内存时,如果不调用setter方法,就会出现相同的问题。
我认为在init/dealloc中直接使用retain/release并不能实现任何目标。你只是改变了可能出现的错误集合。
每次都必须考虑属性分配/释放的顺序。