简体   繁体   English

在init中引发异常时如何防止泄漏?

[英]How do you prevent leaks when raising an exception in init?

Here's the situation. 这是情况。 Let's say I have a class called MYFoo. 假设我有一个名为MYFoo的课程。 Here's it's initializer: 这是初始化程序:

-init
{
  self = [super init];
  if (self)
  {
    // during initialization, something goes wrong and an exception is raised
    [NSException raise ...];
  }
  return self;
}

Now somewhere else I want to use a MYFoo object, so I use a common pattern: 现在我想在其他地方使用MYFoo对象,所以我使用了一个常见的模式:

MYFoo *foo = [[[MYFoo alloc] init] autorelease];

But what's going to happen is that, even if there's a try/catch around the 2nd part, a MYFoo object is going to be allocated, the exception will be thrown, the autorelease missed, and the uninitialized MYFoo object will leak. 但是会发生的是,即使第二部分有一个try / catch,也会分配一个MYFoo对象,抛出异常,自动释放错过,未初始化的MYFoo对象将泄漏。

What should happen here to prevent this leak? 这里应该发生什么来防止这种泄漏?

The Apple Docs say the best practice is not to throw. Apple Docs说最好的做法不是扔掉。

Handling Initialization Failure 处理初始化失败

In general, if there is a problem during an initialization method, you should call [self release] and return nil. 通常,如果在初始化方法期间出现问题,则应调用[self release]并返回nil。

If you need to know what happened, you can init the object and have some kind of internal state that gets checked by the caller to ensure the object is usable. 如果您需要知道发生了什么,可以init对象并使某种内部状态被调用者检查以确保该对象可用。

ongle is 100% right. ongle是100%正确的。 But if you do need to throw an exception and you do want to catch it somewhere (as opposed to just bailing out of the application), you can wrap your initialisation in @try { ... } @finally { ... } 但是如果你确实需要抛出一个异常而你确实希望在某个地方捕获它(而不是仅仅从应用程序中退出),你可以将你的初始化包装在@try { ... } @finally { ... }

-init
{
   self = [super init];
   if (self)
   {
       @try
       { 
           // during initialization, something goes wrong and an exception is raised
           @throw...
       }
       @finally
       {
           [self release]; 
       }
   }
   return self;
}

If you do the above, you should document that the init method can throw an exception because otherwise other users of your code will expect the default behaviour and possibly not write exception safe code. 如果执行上述操作,则应记录init方法可能引发异常,否则代码的其他用户将期望默认行为,并且可能不会编写异常安全代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM