1

I have a problem with retainCount

NSLog(@"%i", [self.albumReceiver retainCount]);
    self.albumReceiver = [[[FacebookAlbumsDelegateReceiver alloc] init: self] autorelease];

    NSLog(@"%i", [self.albumReceiver retainCount]);

The retain count on the first line is 0 but when it gets to third line is 3. The property on self.albumReceiver is retain property... But as far as i can see it should be 2 where other later retain count should went to 1 since it was autorelease later.

 NSLog(@"%i", [self.albumReceiver retainCount]);
    albumReceiver = [[[FacebookAlbumsDelegateReceiver alloc] init: self];

    NSLog(@"%i", [self.albumReceiver retainCount]);

the retain count start with 0 and in this case the second retain count print 2....

Can somebody give some idea of how this retain and release work....

I thought without 'self' keyword, it will ignore the setter call is it? But if i put autorelease on the second example, i will have error.

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
LittleFunny
  • 8,155
  • 15
  • 87
  • 198
  • It is generally a bad idea to pay any attention to the `retainCount` of an object in Objective-C because it is usually impossible to know which secret parts of the frameworks feel a need to retain the object. – mttrb May 31 '12 at 09:14
  • 2
    [Do not use -retainCoun](http://stackoverflow.com/a/3730835/194544) – beryllium May 31 '12 at 09:15

4 Answers4

4

Firstly, the retain count is an implementation detail that you should not be overly concerned with. You should really only care about ownership.

Having said that, the explanation for what you are seeingis as follows:

The retain count on the first line is 0

That's because self.albumReceiver is nil at that point. On real objects, you will never see a retain count of 0 (in the current implementation of Foundation).

when it gets to third line is 3

Normally you would expect the retain count to be 2, +1 for the alloc and +1 for assignment to a retain property. However, the init: method might cause some other object to retain it, so might the setter for the property. Another object observing the property might choose to retain the object too. In short, unless you know the exact implementation of all the methods involved and you know for sure nothing is using KVO on albumReceiver, all you can say about the retain count is that self has ownership of it (NB ownership is not exclusive, other things may also have ownership). This is why you shouldn't pay too much attention to retain counts.

Can somebody give some idea of how this retain and release work

Yes. You need to think in terms of ownership. Certain methods give you an object that you own. These are any method starting with alloc, any method starting with new, any method starting with copy or mutableCopy and -retain. If you receive an object in any other way, you do not own it. That includes receiving them as a return result of a method, ass parameters of a method or as by reference parameters of a method or as global or static variables.

If you own an object, you must relinquish ownership by either releasing or autoreleasing it, or it will leak. If you do not own an object, you must not release or autorelease it.

I find that it is best to think of "you" in the above as meaning "the scope in which the object reference was declared".

Anyway, I recommend you to read Apple's Memory Management Rules for the definitive explanation and not to trust answers here. If you look at the original edit for this answer, you'll see that I got the rules slightly wrong because they have been tightened up since I last read them.

JeremyP
  • 84,577
  • 15
  • 123
  • 161
2

Do not use retainCount. (For situations where it’s appropriate to use it, see this website.) Further reading: blog post by bbum, previous SO thread one, thread two. Also note that retainCount is deprecated in recent SDKs. It’s a good idea to pay attention to the deprecation warnings, and even better idea to turn all warnings into errors.

Community
  • 1
  • 1
zoul
  • 102,279
  • 44
  • 260
  • 354
2

It is generally a bad idea to pay any attention to the retainCount of an object in Objective-C because it is usually impossible to know which secret parts of the frameworks feel a need to retain the object.

In the case you cite where you are adding the object to the autorelease pool, the autorelease pool will presumably be retaining the object until it comes time to flush the pool (during the runloop). This probably explains why the retain count is higher for the autoreleased object.

Note the use of the words "presumably" and "probably" in the above paragraph. I have no idea if this is actually what is happening inside the Cocoa/Cocoa Touch frameworks. This is the problem with using retainCount, you have no way of knowing what the retain count should be at any moment.

If you retain the object (or create it with a method name that contains alloc, copy, mutableCopy or new), you release it. The frameworks are free to also retain the object and they will release it when they are ready. When the retain count reaches zero it will be dealloced.

Update: Having looked at the GNUStep source code for NSObject and NSAutoreleasePool my possible explanation above probably isn't what is happening. However, I have no way to check for sure because I can't see Apple's implementation of these two objects. Even more reason not to trust retainCount or any inferences from it.

mttrb
  • 8,297
  • 3
  • 35
  • 57
  • 1
    Actually, *conceptually*, the retain count doesn't change when you autorelease, because that passes ownership from you to the autorelease pool. In practice, as you say, who knows or cares. – JeremyP May 31 '12 at 09:43
  • Yeah, that was the point I was trying to make. I really don't know why the autoreleased version would have a higher retain count than the one that isn't and as you say "who knows or cares" – mttrb May 31 '12 at 09:46
  • @JeremyP So apparently I care enough to go and look at the GnuStep source code for NSObject and NSAutoreleasePool. You are right it does look like ownership is just handed off to the autorelease pool. Of course Apple may do it differently and I have no way of knowing for sure. – mttrb May 31 '12 at 09:51
0

The only rule that really exists in environments with manual memory management is

If you use alloc, copy, mutableCopy, new

release it. Otherwise DON'T. retainCounts don't really work for debugging. See here

Community
  • 1
  • 1
pbx
  • 1,137
  • 7
  • 15