首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >目标C-记忆管理问题?

目标C-记忆管理问题?
EN

Stack Overflow用户
提问于 2010-11-18 00:59:51
回答 5查看 229关注 0票数 0

我知道,当将保留的属性设置为分配的对象时,它会增加对象的保留计数,因此我需要释放它(第3行,第一个代码块)。

但是,如果我没有属性,并且将分配的对象分配给一个即时变量,该怎么办?我还需要发布它吗?(第3行,第二块代码)

代码语言:javascript
复制
@property (nonatomic, retain) MyObject *myObject;

MyObject *obj = [[MyObject alloc] init];
self.myObject = obj;
[obj release];

代码语言:javascript
复制
MyObject *myObject;

MyObject *obj = [[MyObject alloc] init];
myObject = obj;
[obj release];

在标记为重复的之前请阅读详细信息

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-11-18 08:30:14

我将假设,在这两个示例中,独立的行是类接口中定义的属性和实例变量。其他代码是从同一类中的某个方法执行的。

让我们看看发生了什么:

代码语言:javascript
复制
@property (nonatomic, retain) MyObject *myObject;

MyObject *obj = [[MyObject alloc] init];  // Retain count = 1
self.myObject = obj;         // Retain count +1 (2), because property is defined
                             // as retain.
[obj release];               // Retain count -1

在本例中,一切都按其应有的方式工作。让我们来看看第二个:

代码语言:javascript
复制
MyObject *myObject;

MyObject *obj = [[MyObject alloc] init];  // Retain count = 1
myObject = obj;              // Retain count still 1. Assigns never changes
                             // retain counts.
[obj release];               // Retain count -1 (0), object is now deallocated.
                             // Any access to it though obj or myObject WILL
                             // cause a crash.

您实际上可以编写Objective代码,并将其视为几乎100%的垃圾收集,您只需信任自动发布池即可。当您分配一个对象时,您还应该立即将它交给自动释放池。那样的话,你只需要担心在当前方法结束后保留你想要生存的东西。

您的第一个例子可以是:

代码语言:javascript
复制
@property (nonatomic, retain) MyObject *myObject;

MyObject *obj = [[[MyObject alloc] init] autorelease];
self.myObject = obj;        // Implicitly retain through property

你的第二个应该是:

代码语言:javascript
复制
MyObject *myObject;

MyObject *obj = [[[MyObject alloc] init] autorelease];
myObject = [obj retain];    // Explicitly retained to survive end of method

正如您所看到的,在分配新对象时简单地添加autorelease,并且始终如一地使用属性将减少内存管理,只在dealloc方法中释放实例变量。

票数 0
EN

Stack Overflow用户

发布于 2010-11-18 13:35:00

我知道,当将保留的属性设置为分配的对象时,它会增加对象的保留计数,因此我需要释放它(第3行,第一个代码块)

不,你不知道。例如

代码语言:javascript
复制
foo = [[NSString alloc] initWithString: @"foo"];
[self setMyProperty: foo];

不会增加保留计数,保留计数从INT_MAX开始并停留在那里。但是,--这些都是实现细节,不应该考虑。你真的应该从所有权和想放弃所有权的角度来思考。

在第一个代码块中,一旦退出变量obj,它就会超出作用域。您需要将release发送到它的原因与以下事实无关:您已经将它分配给一个属性,而这一切与您不再对您拥有的对象感兴趣这一事实有关(因为指向它的指针即将超出范围)。顺便说一句,我们所说的“你”是指指针存在的范围。

在第二种情况下,将对象分配给实例变量。实例变量的存在时间,只要它们是实例变量的对象。因此,您需要拥有它,直到对象被解除分配,或者实例变量被更改为指向另一个对象。

票数 1
EN

Stack Overflow用户

发布于 2010-11-18 01:04:16

在您的第二个示例中,objmyObject在调用-release之后都已被取消分配,因为保留计数从1变为零。在第一个示例中,由于您的@property有" retain ",所以retain计数从1变为2,然后在释放它时返回到1,所以它不是dealloc的。

简而言之,您不应该释放直接分配给ivar的对象,除非是在您的-dealloc方法中,或者在将其他东西分配给同一个ivar之前。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4210700

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档