在init中调用dealloc?

发布于 2024-09-30 06:36:42 字数 675 浏览 5 评论 0原文

我正在编写一个框架,并且有一个带有自定义 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

情何以堪。 2024-10-07 06:36:42

如果发生错误,在 init 方法内部调用 dealloc 是否安全?

不,像在其他地方一样发送 -release 。即使在 -init 中,您也不能保证当前保留计数为 1。


为什么除了 [super dealloc]-dealloc > 在 -dealloc 中?原因是,即使在对象的 -init 中,您也无法保证其他对象也引用您的对象,因为 [super init] 可能会选择保留目的。

如果[super init]返回的对象的保留计数为1,发送-release将与发送-dealloc具有相同的效果。如果它的保留计数超过 1,则其他东西会认为它拥有该对象,并且释放它会留下无效的指针,因此 -release 仍然是正确的做法。

另外,这

while([self retainCount] != 0){[self release];}

会导致无限循环,并且出于多种原因是一个糟糕的主意。对象的保留计数永远不会降至 0。-release 看起来像这样:

- (id)release
{
    if (retainCount == 1)
    {
        [self dealloc];
    }
    else
    {
        retainCount--;
    }
}

因此循环会将保留计数减少到 1,然后永远不断地调用 dealloc,或者直到它导致堆损坏为止段错误。

除了永远不会达到零之外,保留可能是UINT_MAX(例如在字符串或数字文字中),通俗地说就是“这个对象永远不能被释放”。如果保留计数为 UINT_MAX-release 不会减少它。

Is it safe to call dealloc inside of an init method if an error occoured?

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:

while([self retainCount] != 0){[self release];}

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:

- (id)release
{
    if (retainCount == 1)
    {
        [self dealloc];
    }
    else
    {
        retainCount--;
    }
}

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 is UINT_MAX, -release won't decrement it.

关于从前 2024-10-07 06:36:42

根据文档,您永远不应该直接调用 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).

拥抱影子 2024-10-07 06:36:42

正如 Vladimir 所说,你永远不应该直接调用dealloc。当对象的保留计数达到0时,Cocoa会自动调用dealloc。

As Vladimir stated you should never call dealloc directly. when retain count of an object reaches 0, Cocoa automatically calls dealloc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文