views:

153

answers:

5

I have some code which I think has extra release statements.

  1. Is the code incorrect?
  2. What is the end result?

I don't understand memory management well yet - even after reading lots of articles and stackoverflow answers. Thanks for straightening me out.

Update: The attached snippet works fine, but other code has the over-release problem

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

Take a look at this article online: http://weblog.bignerdranch.com/?p=2 .

It seems to imply that calls to release without a corresponding preior call to retain will result in a BAD_ACCESS error.

LBushkin
you also need to know when objects retain count increases (which is not only when you call retain) newly allocated objects return a retain count of +1
Daniel
A: 

A short answer is, if you increasing the retain count of an object and you no longer are using it you should release it, otherwise you shouldnt...

So when ever you do a [objectName alloc] you are increasing the count by 1, when you use such methods as [NSString stringWithString:] these methods return an autoreleased object so you dont need to release it...if you instead did something like [[NSString stringWithString:]retain] then you are increasing the strings retain count and you should release it after you are done using it.

Im not too sure if new increases the reference count (i suspect that it would), you can always check your retain count by doing [object retainCount]... though note that even if the retain count is greater than 0, it does not mean you need to release the object, because some other class might have a reference to the object and therefore has its retain count increased by one and its the responsibility of the other class holding the reference to release it.

Hope this helps

Daniel
+new s not a keyword. It is a method and it is documented. It is synonymous with calling alloc and then init and implies a retain. This answer is a bit wishy-washy; I'd recommend reading the cocos memory management guidelines as it is quite clear.
bbum
A: 

you should use:

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

if unsure, use the build->analyze command, it will search your code for leaked refrences

you can get the official memory management guide from http://www.devworld.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.pdf

Lorenzo Boccaccia
Analyze often gets it wrong, I wouldn't rely on it.
Paul Lynch
yeah, but it's a nice starting point to dig further.
Lorenzo Boccaccia
+6  A: 

Your code is correct, but inadvisable. new acts as an implied alloc, which creates the object with a retain count of 1.

I think the last time I used new was in 1992; it's not wrong, but alloc/init is considered better practice, because it is clearer what you are doing. Please read Apple's guide to memory management, it is a comprehensive summary of the situation.

Paul Lynch
Alloc/init isn't really considered better in practice. There is nothing wrong with using +new.
bbum
Hi Bill. Using new isn't an error, it works - but it will confuse a newbie, the proof being the initial question here.
Paul Lynch
Well it shouldn't be confusing. +new is specifically mentioned in the memory management rules. If you know them - and you should - you know that +new gives you ownership of the returned object.
JeremyP
My real question is about extra release statements (other places too). However, I did get confused by the new (didn't realize it implied alloc). Thank you.
BankStrong
+5  A: 

No messages can safely be sent to a deallocated object. Once an object has been released a sufficient number of times, it's deallocated. Any further messages sent to that object are going to an object that isn't there anymore. The precise result isn't completely predictable, but it usually ends in a crash. If you're less lucky, it could end in much stranger ways — for example, you could theoretically wind up with an Object A getting dealloced early and Object B allocated in the same memory location, then Object B receiving messages meant for Object A that Object B does understand but isn't supposed to receive at that time.

Basically, follow the rules. Think of it in terms of ownership. If you've claimed ownership, you need to release that ownership. If you don't own the object, you must not release it.

Chuck
What you say is true, but the OP hasn't over-released his array.
Paul Lynch
That's true — and the link I gave says as much.
Chuck