在init中调用dealloc?
我正在编写一个框架,并且有一个带有自定义 init 方法的对象:
@implementation OSDatabase
@synthesize database;
// MEM
- (void)dealloc {
sqlite3_close(database);
[super dealloc];
}
// INIT
- (id)initWithDatabasePath:(NSString *)path error:(NSError **)error {
if (self = [super init]) {
if (!sqlite3_open_v2([path UTF8String], &database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL)) {
error = [NSError errorWithDomain:@"OSDatabaseErrorDomain" code:1 userInfo:nil];
[self dealloc];
return nil;
}
}
return self;
}
@end
如果发生错误,在 init
方法内部调用 dealloc
是否安全?我对此不确定,内存管理是我一生中最重要的事情之一。
谢谢。
I am writing a framework and I have an object with a custom init method:
@implementation OSDatabase
@synthesize database;
// MEM
- (void)dealloc {
sqlite3_close(database);
[super dealloc];
}
// INIT
- (id)initWithDatabasePath:(NSString *)path error:(NSError **)error {
if (self = [super init]) {
if (!sqlite3_open_v2([path UTF8String], &database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL)) {
error = [NSError errorWithDomain:@"OSDatabaseErrorDomain" code:1 userInfo:nil];
[self dealloc];
return nil;
}
}
return self;
}
@end
Is it safe to call dealloc
inside of an init
method if an error occoured? I'm not sure about this and memory management is one of the most important things in my life.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不,像在其他地方一样发送
-release
。即使在-init
中,您也不能保证当前保留计数为 1。为什么除了
[super dealloc]
-dealloc > 在-dealloc
中?原因是,即使在对象的-init
中,您也无法保证其他对象也引用您的对象,因为[super init]
可能会选择保留目的。如果
[super init]
返回的对象的保留计数为1,发送-release
将与发送-dealloc
具有相同的效果。如果它的保留计数超过 1,则其他东西会认为它拥有该对象,并且释放它会留下无效的指针,因此-release
仍然是正确的做法。另外,这
会导致无限循环,并且出于多种原因是一个糟糕的主意。对象的保留计数永远不会降至 0。
-release
看起来像这样:因此循环会将保留计数减少到 1,然后永远不断地调用 dealloc,或者直到它导致堆损坏为止段错误。
除了永远不会达到零之外,保留可能是
UINT_MAX
(例如在字符串或数字文字中),通俗地说就是“这个对象永远不能被释放”。如果保留计数为UINT_MAX
,-release
不会减少它。No. send
-release
like you would everywhere else. Even in-init
you can't guarantee that the current retain count is 1.Why must you never ever send
-dealloc
except[super dealloc]
in-dealloc
? The reason is that you cannot ever guarantee that something else also has a reference to your object, even in your object's-init
because the[super init]
might choose to retain the object.If the object returned by
[super init]
has a retain count of 1, sending-release
will have the same effect as sending-dealloc
. If it has a retain count of more than 1, something else thinks it owns the object and deallocing it would leave it with an invalid pointer, so-release
is still the right thing to do.Also, this:
would result in an infinite loop and is a terrible idea for a number of reasons. The retain counts of objects never go down to 0.
-release
looks something like this:so the loop will decrement the retain count to 1 and then continually call dealloc forever or until the heap corruption it has caused leads to a seg fault.
Apart from never reaching zero, the retain may be
UINT_MAX
(for example in string or numeric literals) which colloquially means "this object must never be deallocated". If the retain count isUINT_MAX
,-release
won't decrement it.根据文档,您永远不应该直接调用 dealloc - 仅在自定义 dealloc 中调用
[super dealloc]
方法。我认为调用
release
应该执行预期的操作(至少如果您仅在标准 alloc-init 模式中使用 init 方法)。Per docs you should never call dealloc directly - only
[super dealloc]
method in your custom dealloc.I think calling
release
instead should do what expected (at least if you use init method only in standard alloc-init pattern).正如 Vladimir 所说,你永远不应该直接调用dealloc。当对象的保留计数达到0时,Cocoa会自动调用dealloc。
As Vladimir stated you should never call
dealloc
directly. when retain count of an object reaches 0, Cocoa automatically callsdealloc
.