[英]Use of setter in dealloc in Objective C?
以下代码有问题吗?
- (void) dealloc {
self.foo = nil;
}
代替
- (void) dealloc {
[_foo release];
_foo = nil;
}
不采用前者有两个原因:
如果子类已覆盖设置程序,则释放可能实际上不会发生。
使用设置器可能会触发KVO通知,并且观察者将从技术上不存在的对象收到通知。
另一方面,如果使用ARC,则无需执行任何操作。
不建议这样做的原因是它可能会引起问题。 setter或getter可能有副作用
以内存泄漏为例。
- (void)dealloc;
{
self.iWillLeak = nil;
self.iCauseTheLeak = nil;
[super dealloc];
}
- (void)setICauseTheLeak:(NSArray *)iCauseTheLeak;
{
if (_iCauseTheLeak != iCauseTheLeak) {
[_iCauseTheLeak release];
_iCauseTheLeak = [iCauseTheLeak retain];
}
self.iWillLeak = [NSArray array]; // This was already cleared in dealloc
}
这是一个简单的案例,并且有可能发生更具破坏性的事情。
这里的主要结论是,两者在做不同的事情时并不等同。
如果您使用retain
或copy
属性声明了foo
属性,则没有问题,但是如果使用assign
,则不应该执行[_foo release];
您可能会发现以下阅读很有用: 惰性的Objective-C内存管理
我将写两个例子:
1 /直接使用发布
- (void)dealloc {
[foo_ release];
[super dealloc];
}
- (void)setFoo:(Foo*)foo {
if (foo == foo_) {
return;
}
[foo_ removeObserver:self];
[foo_ release];
foo_ = [foo retain];
[foo_ addObserver:self];
}
foo_
的观察者将不会被删除,这可能是一个错误。
2 /使用二传手
- (void)dealloc {
self.observer = nil;
self.foo = nil;
[super dealloc];
}
- (void)setFoo:(Foo*)foo {
if (foo == foo_) {
return;
}
[foo_ removeObserver:self.observer];
[foo_ release];
foo_ = [foo retain];
[foo_ addObserver:self.observer];
}
如您所见,这里出现另一个错误。 我们在可能不会出现nil
某个地方使用nil
( self.observer
)。
通常,这两种情况都不会帮助您捕获错误。 在每种情况下,都会出现不同类型的越野车行为。
我的建议是使用二传手保持一致性,但这是一个见解。 无论如何,如果您编写自己的setter,请检查是否按正确的顺序初始化和取消分配属性。 还要注意,您的设置器可以在子类中被覆盖。
Apple建议直接在init和dealloc中使用保留/释放,但是在自己的代码中,他们使用setter(例如, UITableView
在分配时使用nil
参数调用setDelegate
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.