Objective c 在init中调用dealloc?

Objective c 在init中调用dealloc?,objective-c,dealloc,init,nsobject,Objective C,Dealloc,Init,Nsobject,我正在编写一个框架,我有一个带有自定义init方法的对象: @implementation OSDatabase @synthesize database; // MEM - (void)dealloc { sqlite3_close(database); [super dealloc]; } // INIT - (id)initWithDatabasePath:(NSString *)path error:(NSError **)error { if (self = [sup

我正在编写一个框架,我有一个带有自定义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
安全吗?我不确定这一点,内存管理是我生活中最重要的事情之一


谢谢。

对于每个文档,您不应该直接调用dealloc-在自定义dealloc中仅调用
[super dealloc]
方法

我认为调用
release
应该达到预期的效果(至少如果您仅在标准allocinit模式中使用init方法)

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

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


为什么除了在
-dealoc
中发送
[super dealoc]
之外,您永远都不能发送
-dealoc
?原因是,即使在对象的
-init
中,您也无法保证其他对象也会引用您的对象,因为
[super init]
可能会选择保留该对象

如果
[super init]
返回的对象的保留计数为1,则发送
-release
将与发送
-dealoc
具有相同的效果。如果它的retain计数大于1,则其他人会认为它拥有该对象,取消分配该对象将使其保留无效指针,因此
-release
仍然是正确的做法

此外,这:

while([self retainCount] != 0){[self release];}
将导致无限循环,这是一个可怕的想法,原因有很多。对象的保留计数永远不会下降到0<代码>-release
看起来像这样:

- (id)release
{
    if (retainCount == 1)
    {
        [self dealloc];
    }
    else
    {
        retainCount--;
    }
}
因此,循环将把retain count减为1,然后永远继续调用dealloc,或者直到它导致的堆损坏导致seg错误


除了从不达到零之外,retain可能是
UINT_MAX
(例如字符串或数字文本),通俗地说,这意味着“这个对象永远不能被释放”。如果保留计数为
UINT\u MAX
-release
不会减少它。

正如弗拉基米尔所说,您不应该直接调用
dealloc
。当对象的保留计数达到0时,Cocoa会自动调用
dealloc

而([self-retainCount]!=0){[self-release];}
?@Koning-Baard:否!那同样糟糕。我将编辑我的答案来解释原因。“一堆粪便”几乎不能说明这是多么的错误……:)
-retainCount
可以返回各种内容,包括
UINT\u MAX
。在调试之外,永远不要使用它,即使这样,它也不总是有用的。尤其是ARC。@FireLizzard是正确的,但如果你刚刚发表了评论,让我修改答案,而不是你重写部分,我会更高兴。