views:

417

answers:

4

Just curious if there is anyway to display an objects retain count using NSLog. I just want to print them out to console to help learn how retain/release is working in some simple code?

cheers -gary-

+2  A: 

Not only is it possible, it's very easy too:

NSLog(@"retain count=%d",[obj retainCount]);
Philippe Leybaert
Note that retain counts are an implementation detail and they can and do work in ways that make no sense to an outside observer. In other words, this is not a particularly useful thing to do. Better to read the memory management guidelines ( https://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/MemoryMgmt/index.html ) and follow the simple rules of ownership.
Chuck
technically it should be %u because retainCount returns an NSUInteger (in practice it will never get big enough to matter though)
newacct
@Chuck: technically you are correct, but in real life it can sometimes help you pinpoint retain/release problems.
Philippe Leybaert
@Philippe: Technically you are correct, but in real life it can lead you down all sorts of false paths because objects are under no obligation to implement their memory management the way you expect. So many frustrated questions on Stack Overflow boil down to somebody looking at a retain count and wrongly expecting it to behave in a certain way.
Chuck
I can't argue with that, but one one occasion logging the retainCount has helped me find a stupid bug.
Philippe Leybaert
A: 

In the debugger console, you could type: print (unsigned int)[thing retainCount]

ennuikiller
A: 

Hmm -- I get a long and unchanging number -- something I'm doing wrong?

NSString *A = [[NSString alloc] init];

NSLog(@"%u", [A retainCount]);

[A retain];

NSLog(@"%u", [A retainCount]);

PRINTS: 2147483647 both times

MonthlyRetainer
2147483647 doesn't seem like a very realistic retainCount now does it?
micmoo
Because retain counts are an implementation detail and the absolute retain count is almost never interesting and often misleading. In this case, it is because you happened to have grabbed the global empty immutable string instance whose class has overridden retain/release/autorelease/retainCount to do pretty much nothing.
bbum
A: 

I think you might be hitting an issue with NSString where retain and release messages can be sent to a string constant, but they actually have no effect nor alter the objects retainCount. The code below works, change it to use NSString and retain / release have no effect.

Code:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSMutableString *myString = [[NSMutableString alloc] initWithString:@"AB"];
    NSLog(@"RC: %d", [myString retainCount]);
    [myString retain];
    NSLog(@"RC: %d", [myString retainCount]);

    [myString release];
    NSLog(@"RC: %d", [myString retainCount]);
    [myString release];

    [pool drain];
    return 0;
}

Output:

Running…
TESTBED[12306:a0f] RC: 1
TESTBED[12306:a0f] RC: 2
TESTBED[12306:a0f] RC: 1

gary

fuzzygoat