繁体   English   中英

Objective-C记忆模型

[英]Objective-C memory model

我试图将我的头缠在Objective-C内存模型的一部分上(特别是在iPhone上,因此没有GC)。 我的背景是C / C ++ / Java,下面的代码存在问题(也想知道我是否以“ Objective-C方式”执行此操作):

- (NSSet *) retrieve
{
    NSMutableSet *set;

    set = [NSMutableSet new];
    // would normally fill the set in here with some data

    return ([set autorelease]);
}

- (void) test
{
    NSSet *setA;
    NSSet *setB;

    setA = [self retrieve];
    setB = [[self retrieve] retain];

    [setA release];
    [setB release];
}

开始编辑

根据以下注释,更新了检索方法:

- (NSSet *) retrieve
{
    NSMutableSet *set;

    set = [[[NSMutableSet alloc] initWithCapacity:100] autorelease];
    // would normally fill the set in here with some data

    return (set);
}

结束编辑

上面的代码为[setA release]提供了警告“调用者此时不拥有对象引用计数的不正确减少”。

我虽然说“ new”将引用计数设置为1,但是“ retain”调用将添加1,而“ release”调用会将其删除1。给定的情况是setA的引用计数不会为0。 end和setB的引用计数最终是否为1?

根据我的尝试和发现,setB是正确的,并且没有内存泄漏,但是我想了解为什么会这样(我对“ new”,“ autorelease”的理解有什么问题, “保留”和“释放”)。

我虽然说“ new”将引用计数设置为1,但是“ retain”调用将添加1,而“ release”调用会将其删除1。给定的情况是setA的引用计数不会为0。 end和setB的引用计数最终是否为1?

您将autorelease -(void)test得到一个集合时,它的保留计数为0。您没有保留setA ,因此当您尝试释放它时,它的保留计数已经为0,因此会出现错误消息。

内存管理基本规则非常简单:对allocnewcopy*的调用必须通过对release / autorelease调用来平衡。 前者取得所有权,后者放弃所有权。

唯一棘手的部分是在处理共享库时 ,您不拥有对象的所有权,因此在您获得对它的引用与使用之间,它可能会被丢弃。 这有一个简单的解决方案:如有疑问,请保留它。

通过在许多情况下使用属性 ,可以使事情变得更加简单。

不要以绝对数字来思考。 那可能是非常具有欺骗性的。 如果您必须有一个数字,则将保留和释放视为增量-在这种情况下, autorelease已使new平衡(+1增量和-1增量),因此该方法可以正确地管理其内存,而接收方则不会需要做任何事情,除非它想让对象保持更长的时间。

一定要阅读内存管理文档 确实很简单,只需遵循此处描述的规则。 这是一个非常简单的所有权合同,当您希望对象随处可见时,您可以主张所有权;而当您不再关心对象时,则放弃所有权。 在上述情况下,您在retrieve方法中放弃了所有权,因此,在没有所有权时尝试放弃所有权显然是一个错误。

正如探查器消息提示的那样,您应该考虑所有权。 内存管理规则中所述 ,每当您拥有使用+alloc+new-copy-mutableCopy创建的对象时,便拥有该对象并最终负责释放它。 (实际上, +new只是[[MyClass alloc] init]简写。)

-retain接受一个您最初不拥有的对象,并使您拥有它。

-release获取您拥有的对象并释放其所有权。

-autorelease获取您拥有的对象并释放其所有权, 但也保证该对象至少存在一点时间

您的-retrieve方法不会转移它返回的对象的所有权。 很好-它遵循内存管理规则(该方法不是+alloc+new-copy-mutableCopy )。 因此,在不使用-retain情况下使用-release是错误的。 只要对象具有临时生存期,不保留或释放-retrieve的结果同样有效—您的-autorelease保证对象的临时存在。

http://www.macresearch.org/difference-between-alloc-init-and-new

你可能想要

NSMutableSet *set = [[NSMutableSet alloc] initWithCapacity: someNumber];

要么

NSMutableSet *set = [NSMutableSet setWithCapacity: someNumber];

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM