iPhone分配和释放

Posted

技术标签:

【中文标题】iPhone分配和释放【英文标题】:iPhone alloc and release 【发布时间】:2011-08-05 11:43:23 【问题描述】:

我是 ObjC 和 iPhone 的新手。

我下载了一个在多个视图之间共享数据的示例。基本方法是在基础 UIApplication 中创建一个数据模型对象并从中获取/设置数据。所以在init方法中我看到了以下代码:


- (id) init;

    self.theAppDataObject = [[ExampleAppDataObject alloc] init];
    [theAppDataObject release];
    return [super init];

然后,使用委托我们可以访问这个对象。


id theDelegate = (id) [UIApplication sharedApplication].delegate;
    ExampleAppDataObject* theDataObject;
    theDataObject = (ExampleAppDataObject*) theDelegate.theAppDataObject;

所以,我的问题是在第一个代码示例中。为什么我们需要为 theAppDataObject 对象分配内存,然后立即释放该对象?为什么我们以后访问这个对象时不得到 nil 呢?

10 倍

【问题讨论】:

那个例子的来源是什么?它没有遵循 init 方法的官方最佳实践(即第一行应该类似于 if (!(self = [super init])) return nil; 【参考方案1】:

我假设theAppDataObject 被声明为@property (retain)。因此,当通过self.theAppDataObject(或[self setTheAppDataObject:])设置对象时,该属性将保留ExampleAppDataObject。因此,您可以在之后发布它。

当您分配和初始化 ExampleAppDataObject 时,它的保留计数上升到 1。当您将 AppDataObject 设置为此 ExampleAppDataObject 时,它会向它发送保留,因此保留计数上升到 2。然后您可以释放自己的所有权对象的;它不会被释放,因为 AppDataObject 仍然拥有所有权。

如果这有意义的话。

【讨论】:

好的。你是对的。但是为什么 alloc 和 init 行将计数增加到 2? alloc init 行将ExampleAppDataObject 的保留计数增加到1。当您使用theAppDataObject 的设置器时,此对象将retain 发送到ExampleAppDataObject,并且它的保留计数上升到2.因此您可以释放您对该对象的所有权。【参考方案2】:

这取决于 AppDataObject 属性是如何定义的。 如果它提供了一个保留 setter-accessor,则 appDataObject 的保留计数将翻转为 2,比此处需要的多一个。

所以释放其中一个。

更好和更容易理解的方法是写

if ( (self = [super init]) ) 
    ExampleAppDataObject *myAppDataObject = [[ExampleAppDataObject alloc] init];
    self.theAppDataObject = myAppDataObject;
    [myAppDataObject release];


return self;

【讨论】:

【参考方案3】:

Iphone 使用基于引用计数的内存管理模型..先看this 教程,然后再看apple's 技术文档... theAppDataObject 是一个属性(参见 self.theAppDataObject 的使用),上面的代码应该保留它工作..任何被保留的对象都应该有一个奖励加上 1 个保留计数...一个对象只有在其保留计数变为零时才会被释放..

【讨论】:

【参考方案4】:

第一件事:代码示例很糟糕。

- (id) init

    // assign self. super may return another address
    self = [super init];
    // then check for nil
    if (self != nil) 
            // then assign the ivar directly because you should
            // not invoke methods of partially constructed objects
        theAppDataObject = [[ExampleAppDataObject alloc] init];
    
    // then return the address super returned
    return self;

现在回答您的问题:

为什么我们需要为 theAppDataObject 对象分配内存,然后立即释放该对象?

self.theAppDataObject 通过设置器调用,它保留、复制或分配theAppDataObject。在这种情况下,我们可以假设它很有可能被保留。

为什么我们以后访问这个对象时不得到 nil 呢?

release 没有将指针设置为 nil。它向对象发送一条消息,然后减少保留计数(在典型情况下)。在这种情况下,您可能期望的是一个已被释放的对象。保留参数时不会发生这种情况,因为在您显示的程序中引用计数未达到零。该对象仍然存在,因为它已被保留,并且在调用 setter (self.theAppDataObject = arg) 时存储了该对象的地址。

【讨论】:

以上是关于iPhone分配和释放的主要内容,如果未能解决你的问题,请参考以下文章

iPhone:AudioBufferList 初始化和释放

分配给 iphone sdk 中已分配的变量

内存泄漏 - iPhone

iPhone:在对象上调用释放:它会立即释放吗?

Iphone 打开 gl es 应用程序和自动释放池

iPhone - SKProductsRequest 和“发送到已释放实例的消息”