2012-02-26 69 views
0

我正在学习objectiveig和编程一个iPad应用程序。内存管理是我不断重复并不得不重新阅读的一件事。我到达那里......慢慢地。基本规则如每alloc/retain你必须有release是有用的。然而,一个比较基本的东西躲开我,我不知道是否有人能解释...了解ios中的内存管理

看看下面的代码...

NSArray *myArray = [[NSArray alloc] init]; 
myArray = [someNSSet allObjects]; 

这是相对简单的编码,并且将需要[myArray release]声明。

不过,我一直看到的例子(实际上,我已经广泛以下“捷径”用...

NSArray *myArray = (NSArray *)[someNSSet allObjects]; 

如何,据我了解,当你使用你不要的(NSString *)需要使用[myArray release]声明,但我不明白为什么。

可能有人可能解释?

回答

1

在第一行:

NSArray *myArray = [[NSArray alloc] init] 

一定数量的内存分配给一个数组(实际上在这种情况下,它是毫无意义的,因为数组的大小为0。请记住,NSArray中是不变的! )。 变量myArray保存保留内存区域的第一个字节的地址。

现在在第二行中,您将更改myArray的值,该值现在将指向存储[someNSSet allObjects]的内存区域的第一个字节。在这一刻,你不知道数组的存储位置是在第一行创建的。所以你有泄漏。

行:

NSArray *myArray = (NSArray *)[someNSSet allObjects]; 

是正确的,因为你没有在这一点上预留的内存。如果您不使用ARC,则可能会调用retain以使GC远离引用的内存块。换句话说,当对象的所有者释放它并尝试访问它时,您可能会收到BAD_EXEC例如:[myArray objectAtIndex:0]

2
NSArray *myArray = [[NSArray alloc] init]; 
myArray = [someNSSet allObjects]; 

此代码泄漏myArray,因为您失去了在第一行分配的NSArray的引用;这里您不需要alloc,因为在第二行中,您将为myArray分配一个新值。

NSArray *myArray = (NSArray *)[someNSSet allObjects]; 

与此代码示例是完全没有问题,你分配的[someNSSet allObjects]myArray指针的结果,你没有自己的返回值,所以你不必在意释放它。

考虑为您的项目使用ARC(自动保留计数)。使用ARC,编译器负责保留计数,因此您不必实际不允许这样做。有一个重构将转换当前的项目。

+0

为什么我不拥有返回的值。谁/什么? – 2012-02-26 18:35:29

+0

@BenThompson:当你创建一个对象(new或alloc,copy或mutableCopy)时,它的保留计数为1,并且你拥有它。 当你发送一个对象一个保留消息时,它的保留计数增加1,你也拥有它。您只需要释放您拥有的对象。 – 2012-02-26 18:39:28

+1

@Ben:最有可能的是autorelease池是从'allObjects'返回的对象的所有者。另一种可能性是set对象,但这只会在集合暴露一个已经拥有的对象时才会发生,而不是创建一个新的数组。但是,除了了解背景中发生的事情外,你不应该关心谁拥有事物。无论你做或不做,这都是你需要考虑的。 – 2012-02-26 18:48:55

2

正如您所说,您发布的第一个代码有泄漏。所以你必须添加一个版本:

NSArray *myArray = [[NSArray alloc] init]; 
[myArray release]; 
myArray = [someNSSet allObjects]; 

事实上,当你获得通过,与allocnewcopy,你拥有它开始的方法的对象,你应该释放它。这就是为什么,在这里你应该释放你使用方法alloc获得的数组。这个约定可以很容易地知道你何时拥有对象,什么时候不拥有对象。所以请记住:alloc,newcopy

至于第二实施例,则得到的数组虽然不与这三个词(allocnewcopy)中的一个启动的方法,这样就不会拥有该对象,而你不负责释放它。实际上,您获得的数组是一个自动释放对象,这意味着即使其保留计数当前为1,当被称为autorelease池的内容被耗尽时,它也会自动释放。

以下是关于Memory Management Rules的参考。

+0

可能会更好地在你的答案代码中使用第3行倒行第2行(或者使用autorelease而不是发行版) – meronix 2012-02-26 19:39:13

+0

第2行中的'release'是为了平衡第2行中的'alloc',以便'myArray'的旧值不泄漏。在为myArray分配一个新值之前,我们需要做到这一点。 – sch 2012-02-26 19:44:37

+0

是的,当然,但如果你释放它,在第3行myArray不再存在,它没有更多的分配,可能会给你错误,你不能使用它。你必须平衡alloc和release,并在这两行之间使用你的对象。或不? – meronix 2012-02-26 20:01:15