0

I need to know if the retaincount of objects should always be 0 if i want to have a good memory management in my code. I got the following code from a book. and there's a statement NSLog called after release = 2, So should i have to release it 2 more times so that the retaincount will be 0 ?

#import <Foundation/NSObject.h>
    #import <Foundation/NSAutoreleasePool.h>
   #import <Foundation/NSString.h>
 #import <Foundation/NSArray.h>
 #import <Foundation/NSValue.h>
 int main (int argc, char *argv[])
 {
 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 NSNumber *myInt = [NSNumber numberWithInteger: 100];
 NSNumber *myInt2;
 NSMutableArray *myArr = [NSMutableArray array];
 NSLog (@”myInt retain count = %lx”,
 (unsigned long) [myInt retainCount]);
 [myArr addObject: myInt];
 NSLog (@”after adding to array = %lx”,
 (unsigned long) [myInt retainCount]);
 myInt2 = myInt;
 NSLog (@”after asssignment to myInt2 = %lx”,
 (unsigned long) [myInt retainCount]);
 [myInt retain];
 NSLog (@”myInt after retain = %lx”,
 (unsigned long) [myInt retainCount]);


 NSLog (@”myInt2 after retain = %lx”,
 (unsigned long) [myInt2 retainCount]);
 [myInt release];
 NSLog (@”after release = %lx”,
 (unsigned long) [myInt retainCount]);
 [myArr removeObjectAtIndex: 0];
 NSLog (@”after removal from array = %lx”,
 (unsigned long) [myInt retainCount]);
 [pool drain];
 return 0;
 }

Program Output

myInt retain count = 1
after adding to array = 2
after asssignment to myInt2 = 2
myInt after retain = 3
myInt2 after retain = 3
after release = 2
after removal from array = 1

UPDATE

The following code was taken from the Apples memory management document. They have retained a NSNumber object and its never been released, is this OK ?

- (void)setCount:(NSNumber *)newCount {
[newCount retain];
[_count release];
// Make the new assignment.
_count = newCount;
}
Illep
  • 16,375
  • 46
  • 171
  • 302
  • Note that the retain counts for myInt and myInt2 are the same because the retain count applies to the object, not the pointer variable, and both those pointer variables are pointing to the same object. – Hot Licks Nov 20 '11 at 02:20
  • And note that, in your example, the retain count "after release" is two because there's one count "owned" by the array, and one count "owned" by the autorelease object. – Hot Licks Nov 20 '11 at 02:22
  • 2
    please search Stackoverflow for *retainCount* and see what the coders with an reputation of 5000+ points say about it. – vikingosegundo Nov 20 '11 at 02:25
  • So is it necessary to release the `retainCount` owned by the array ? I don't think i will have to consider releasing the count "owned" by the autorelease object because the `NSAutoreleasePool` will take care of it ? – Illep Nov 20 '11 at 02:27
  • 2
    http://stackoverflow.com/questions/4636146/when-to-use-retaincount – vikingosegundo Nov 20 '11 at 02:28
  • One last question, Apples doc says `You create an object using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” ` and you have to release it. But do i have to `release` objects that i `retain`ed ? – Illep Nov 20 '11 at 03:47
  • The code is misleading, at best. You should *never* be looking at the result of `retainCount`; the returned value is useless and, often, completely misleading. You say that is from a book? What book; there are a bunch of problems with that code and, if you are using that code as a template for the rest of your code, you'll be in for some maintenance headaches in the future. – bbum Nov 20 '11 at 22:36
  • Programming in Objective-C 2.0 by Stephen G. Kochan. Could you please recommend me a good Objective-c/cocoa/cocoa-touch book – Illep Nov 21 '11 at 08:03

2 Answers2

5

You shouldn't be worried about the retain count of your objects, especially because the the NSArray or other objects might retain and then only later release things you pass to them. I'd strongly suggest focusing instead on Objective-C and Cocoa's memory management rules, which ensure that things are cleaned up when needed.

Jesse Rusak
  • 56,530
  • 12
  • 101
  • 102
  • One last question, Apples doc says `You create an object using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” ` and you have to release it. But do i have to `release` objects that i `retain`ed ? – Illep Nov 20 '11 at 03:47
  • That is really a separate question, but the answer is that when you retain something, you own it, and yes, you must release it later. In the example in your question, newCount is set to an ivar which will either be released by the next call to setCount, or in that class's dealloc. – Jesse Rusak Nov 20 '11 at 17:27
1

This is not to take away from existing answers, but to address your edit (Which, by the way, should REALLY be a separate question.):

They have retained a NSNumber object and its never been released, is this OK ?

- (void)setCount:(NSNumber *)newCount {
[newCount retain];
[_count release];
// Make the new assignment.
_count = newCount;
}

Well it wouldn't be, if that was what they did. You are confusing pointers with objects. Do you see the (NSNumber *) just before newCount. That '*' means that newCount is a pointer to an NSNumber object. Allow me to translate.

[newCount retain];

Retain the object referred to by the pointer 'newCount'.

[_count release];

Send a release message to the object currently referred to by the '_count' pointer.

_count = newCount; 

Make the pointer '_count' refer to the object that is referred to by the pointer 'newCount'

Think of it like this, if you have a car you likely just call it myCar. When you say myCar you mean your car, the car you own. Let's say you buy a new car for a while you will call it newCar so that you can tell the difference. So you take ownership of your new car [newCar retain], and for a brief moment you own two cars. Now you sell your old car, which you still call myCar, [myCar release](very sad). But now when you say myCar you mean your newCar myCar = newCar. You no longer own your old car. And now your newCar is just myCar and you own, retain, that one. When you die, dealloc, your car will be sold,[myCar release].

NJones
  • 27,139
  • 8
  • 70
  • 88
  • SO basically, you need not have to `release` `newCount` because we didn't `alloc`/`new`/`copy` it. `newCount` only copies the reference to `_count` (which is the same object in memory), so need not be `release`. Am i correct ? – Illep Nov 20 '11 at 06:18
  • Responded with edit, you need to understand objects vs pointers. – NJones Nov 20 '11 at 07:27