【问题标题】:when to release object that is used throughout the class?何时释放全班使用的对象?
【发布时间】:2011-11-24 21:10:56
【问题描述】:

我知道 Objective-C 中内存管理的基本规则是,对于你执行分配的每个对象,你都需要在某个地方释放它。

假设我有以下内容:

@interface NewPollViewController : UIViewController 
{
   NSMutableArray * myArray;
}

@property (nonatomic, retain) NSMutableArray * myArray;

@implementation NewPollViewController
@synthesize myArray = _myArray;

- (void) viewDidLoad
{
  [super viewDidLoad];
  self.myArray = [[NSMutableArray alloc] init];
}

说这个self.myArray是作为一个UITableView的dataSource使用的,那么我应该在什么时候、什么地方释放这个呢?在交易中?我猜dealloc中的释放对应于我在属性中设置的保留,那么我在哪里释放

【问题讨论】:

    标签: iphone objective-c ipad memory-management


    【解决方案1】:

    在您的示例中,您在技术上需要释放它两次 - 一次在 dealloc 中,一次在设置属性后立即:

    NSMutableArray *a = [[NSMutableArray alloc] init];
    self.myArray = a;
    [a release];
    

    这样做的原因是因为你在viewDidLoad中专门分配内存,然后在设置属性时还增加了保留计数。

    避免这种情况的一种方法是使用静态 NSMutableArray 构造函数之一或使用 autorelease 即

    self.myArray = [[[NSMutableArray alloc] init] autorelease];
    

    或者,完全绕过该属性:

    myArray = [[NSMutableArray alloc] init];
    

    这样可以避免属性产生的额外保留(事实上,如果属性语句只在本地使用,你可以去掉它)。

    【讨论】:

    • 你还想在dealloc发布它。
    • self.myArray = [NSMutableArray array] 可能比alloc、init、autorelease 三重奏更简洁。
    • 我同意 - 我也更喜欢这种形式
    【解决方案2】:

    如果我想公开一个 NSMutableArray,我会这样做:

    @interface NewPollViewController : UIViewController 
    {
       NSMutableArray * myArray;
    }
    
    @property (nonatomic, readonly) NSMutableArray * myArray;
    
    @implementation NewPollViewController
    @synthesize myArray;
    
    - (void) viewDidLoad
    {
      [super viewDidLoad];
      self.myArray = [[NSMutableArray alloc] init];
    }
    
    - (void) dealloc
    {
       [myArray release],myArray = nil;
    }
    

    将属性更改为只读,因为它是可变数组,您不希望其他类更改此数组,并且您已正确分配和释放它。

    【讨论】:

    • NSMutableArray 只是一个例子,它可以是任何对象
    • 如果它的 String Literal 和一个 iVar 分配给它,那么你不会分配和释放它。如果它的 String 对象,您将使用复制,并且不需要在 viewDidLoad 中分配和初始化。通常你不会在带有 retain 的属性上调用 alloc。
    • @Nikita - 从技术上讲,您的代码会泄漏。要在一行中设置属性,您应该使用 NSMutableArray 静态构造函数之一或自动释放。当然,除非您从初始化数组的位置删除“self”。见stackoverflow.com/questions/156243/…
    • 为什么我的代码会泄露?它的只读不保留属性。由于接口 self.myArray 中有一个 iVar,因此与使用 myArray 的效果相同。如果我只是使用没有 iVar 的属性,那么我必须使用 self。
    【解决方案3】:

    在你的情况下,我经常在viewDidUnload 和dealloc 中发布它。

    我喜欢维护一个关于内存分配位置的镜像。在viewWillAppear 完成后,我在viewWillDisappear 发布。

    既然你说这是在整个课程中使用的,我会在init 方法或awakeFromNib 中分配,然后在dealloc 中释放一次。

    【讨论】:

    • 对于您的第三个选项,您仍然必须释放它两次...为什么当您在 init 中的 Lloc 时只需要释放它一次?
    • 因为它与视图无关,或者它是否已加载或可见。当它最终到达dealloc 时,就是你想要释放它的时候。如果这是myArrayOfSubviews,那么您可能会创建加载/卸载并释放以正确响应内存警告。
    猜你喜欢
    • 2015-04-25
    • 2012-05-04
    • 1970-01-01
    • 2011-01-30
    • 1970-01-01
    • 2011-09-01
    • 2011-05-13
    • 2011-11-18
    • 2011-09-06
    相关资源
    最近更新 更多