【问题标题】:removeFromSuperview and release memory managementremoveFromSuperview 和释放内存管理
【发布时间】:2012-01-18 23:53:53
【问题描述】:

我有一个 MBProgressHUD,我分配如下:

 self.progressHUD_ = [[[MBProgressHUD alloc] initWithView:self.view] autorelease];

如果我调用 removeFromSuperview 那么我是否必须再次调用progressHUD release?另外,如果我用这样的东西声明一个属性:

NSString * title_;

@property (nonatomic, retain) NSString * title_;

那么保证在我的dealloc中我应该有一个标题的释放吗?

【问题讨论】:

    标签: iphone objective-c ios ipad


    【解决方案1】:

    如果progressHUD_ 是一个retain 属性,那么你必须在dealloc 中释放它。但是,保留属性的好处是您只需将其设置为 nil 即可回收内存;确保使用“自我”。之前。

    e.g.
    
    self.<property_name> = nil;
    
    // or in your case
    
    self.progressHUD_ = nil;
    
    // the following will not release it because it's not accessing the property:
    
    progressHUD_ = nil
    

    我不建议使用[progressHUD_ release],因为它可能会导致问题。例如如果你在其他地方释放了progressHUD_并且没有将它设置为nil,你可能会意外释放一个不再分配的指针(悬空指针)。

    我还建议在内存不足的情况下调用viewDidUnload 中的self.progressHUD_ = nil; 并且视图未显示。它不会杀死您的类实例,而只是卸载视图。当然,这假设您在 viewDidLoad 而不是 init... 中调用 self.progressHUD_ = [[[MBProgressHUD alloc] initWithView:self.view] autorelease];

    【讨论】:

      【解决方案2】:

      不,您不必再次释放它。当您调用 removeFromSuperview 时,视图会保留其子视图并再次自动释放它们。只要视图在附加到视图时已经自动释放,它就会在从视图中移除时被释放。

      我不太明白您的第二个问题,但是是的,您必须在您的 dealloc 语句中释放“保留”或“复制”类型的任何属性。您必须手动编写这些发布声明,它们不会自动添加(当然,除非您使用 ARC,我强烈建议您这样做)。

      【讨论】:

      • 好吧,基本上如果我定义一个保留在我的 .h 中的属性,那么我将不得不在我的 dealloc 中释放它,这是我的问题
      • 你最好使用 self.title_ = nil;在你的 dealloc 而不是 [title_release] 中,因为这减少了 title_ 已经是以前的版本但没有设置为 nil 的机会,从而让你释放一个悬空指针。
      • @paiego 我完全同意,但我认为大多数程序员实际上是按照 OP 的方式来做的。不过不知道为什么,因为设置为 nil 包括自动发布。
      • 这根本不是真的。将属性设置为 nil 与释放它然后将 ivar 设置为 nil 完全相同 - 它不会保护您免受先前释放的指针的影响。它可以保护您免受指针的 future 版本的影响,但在 dealloc 中,无论如何都不会有未来版本的风险。
      • 另外,通过使用 self.foo = nil;您可能会调用具有额外意外副作用的 setter 方法,这就是为什么苹果明确建议在 dealloc 中使用 release 语句而不是将属性设置为 nil 的原因。不过,在代码中的其他任何地方,您都应该使用该属性,以避免意外留下悬空指针而不将其取消。
      【解决方案3】:

      您的progressHUD_ 属性是如何定义的? (顺便说一句,ivar 应该有一个尾随下划线,但不是属性名称)。

      如果它被定义为(retain, whatever),你必须再次释放它:

      1. 当您创建它时,它的 retainCount 为 +1。
      2. 当您将其分配给您的属性时,其 retainCount 将增加一。
      3. 当你将它作为子视图添加到父视图时,它的retainCount 会加一。
      4. 在某些时候,自动释放最终会将其减 1,但视图和属性仍会保留它。

      因此,您必须将您的属性设置为 nil,或者在您的 dealloc 方法中调用 ivar 上的 release

      另外,在定义 NSString 属性时,您可能希望使用 copy 而不是 retain。是的:无论哪种方式,你都必须释放它。

      【讨论】:

      • 它被定义为@property (nonatomic, retain) progressHUD_;
      • 是的,你必须再次释放它。此外,您可能希望在您的 h 文件中调用您的属性“progressHUD”,然后在您的 m 文件中说 @synthesize progressHUD=progressHUD_;:这样属性称为 progressHUD 和 ivar progressHUD_
      • 是的,您总是需要使用 self 来访问该属性。仅对 ivar 使用下划线,而不是对属性使用下划线会使您的代码更清晰。
      • 绝对保留计数没有意义。
      • @bbum 没错,我并不是说他实际上应该调用 retainCount 或其他任何东西。我只是想概述一下,当您将视图添加到保留它的类的属性时,您仍然必须在您的 dealloc 方法中释放视图。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-11
      • 1970-01-01
      相关资源
      最近更新 更多