2010-04-13 81 views
1

我有一些代码,我认为有额外的发布声明。发布前没有保留危险吗?

  1. 代码不正确?
  2. 最终结果是什么?

我不明白内存管理 - 甚至在阅读大量的文章和stackoverflow的答案。感谢您的理解。

更新:所附的片段工作正常,但其他的代码有过放的问题

NSMutableArray *points = [NSMutableArray new]; 
for (Segment *s in currentWorkout.segments) { 
[points addObjectsFromArray:[s.track locationPoints]]; 
} 
[routeMap update:points]; 
[points release]; 

回答

5

没有消息可以安全地发送到解除分配的对象。一旦一个对象被释放了足够的次数,它就会被释放。发送到该对象的任何进一步的消息将转到不存在的对象。确切的结果不是完全可预测的,但通常以崩溃结束。如果你不那么幸运,它可能以非常陌生的方式结束 - 例如,你可以理论上结束对象A的早期处理,并将对象B分配到同一个内存位置,然后对象B接收对象A的消息,对象B确实了解,但不应该在当时收到。

基本上,follow the rules。从所有权角度考虑它。如果您声明拥有权,则需要释放该所有权。如果你没有自己的对象,你一定不要释放它。

+0

你说的是真的,但OP没有过度释放他的阵列。 – 2010-04-13 17:51:27

+0

这是真的 - 我给出的链接也是如此。 – Chuck 2010-04-13 18:19:39

0

看看这篇文章在网上:http://weblog.bignerdranch.com/?p=2

它似乎意味着调用释放没有相应的preior调用保留将导致BAD_ACCESS错误。

+0

您还需要知道对象何时保持计数增加(这不仅仅是在您调用保留时)新分配的对象返回的保留计数为+1 – Daniel 2010-04-13 15:39:22

0

一个简短的回答是,如果你增加了保留对象的数量和你不再使用它,你应该释放它,否则你不应该...

所以,当你永远做一个[对象名页头]当你使用[NSString stringWithString:]这样的方法时,你正在增加1,这些方法返回一个自动释放的对象,所以你不需要释放它...如果你改为做[[NSString stringWithString:] retain],那么你正在增加字符串保留计数,你应该在完成使用后释放它。

我不太确定,如果新增了引用计数(我怀疑它会),您可以随时通过[对象retainCount]检查您的保留计数...但请注意,即使保留计数大于0 ,这并不意味着你需要释放该对象,因为其他一些类可能有一个对该对象的引用,因此它的保留计数增加1,而其他类的责任持有引用来释放它。

希望这有助于

+0

+ new s不是关键字。这是一种方法,它被记录。它与调用alloc和init是同义词,意味着保留。这个答案有点意味深长;我建议阅读cocos内存管理指南,因为它很清楚。 – bbum 2010-04-13 18:27:36

0

你应该使用:

NSMutableArray *points = [[NSMutableArray alloc] init]; 
[...] 
[routeMap update:points]; //if routemap stores the points, it will need it's own release retain 
[points release]; //if there is a retain in the method above, reference will not be cleared 

如果不确定,使用建设 - > analyze命令,它会搜索你的代码泄露refrences

你可以得到官方内存管理指南http://www.devworld.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.pdf

+0

分析经常出错,我不会依赖它。 – 2010-04-13 15:44:27

+0

是的,但它是进一步挖掘的好起点。 – 2010-04-14 08:21:35

6

您的代码是正确的,但不可取。作为隐含分配的新行为,其创建保留计数为1的对象。

我认为我最后一次使用new是在1992年;这没有错,但是alloc/init被认为是更好的练习,因为它更清楚你正在做什么。请阅读Apple's guide to memory management,这是一个全面的情况总结。

+1

Alloc/init在实践中并不被认为更好。使用+ new没有任何问题。 – bbum 2010-04-13 18:28:42

+0

嗨比尔。使用新的并不是一个错误,它的工作原理 - 但它会混淆新手,证明这是最初的问题。 – 2010-04-13 19:24:02

+0

好吧,它不应该混淆。在内存管理规则中特别提到了+ new。如果你知道他们 - 而且你应该 - 你知道+ new让你拥有返回的对象。 – JeremyP 2010-04-13 20:00:39