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分配和释放的主要内容,如果未能解决你的问题,请参考以下文章