1

Here is my code

#import <Foundation/Foundation.h>

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

    NSString *str = [[NSString alloc]initWithString:@"This is string object"];
    NSLog(@"%lu", [str retainCount]);
    [pool drain];


    return 0;
}

I expected the output to be 1 becase it is newly created object, but the result is 1152921504606846. What is wrong here ?

jrturton
  • 118,105
  • 32
  • 252
  • 268
Profo
  • 153
  • 2
  • 2
  • 11
  • Don't use retainCount. See - [When to use -retainCount?](http://stackoverflow.com/questions/4636146/when-to-use-retaincount) – beryllium Feb 01 '12 at 11:59
  • possible duplicate of [NSString retain Count](http://stackoverflow.com/questions/1390334/nsstring-retain-count) – jscs Feb 01 '12 at 15:05

3 Answers3

6

Three important points:

  1. This has nothing to do with autorelease pools. Your variable is allocd, so it not added to the pool
  2. Never use retainCount for debugging. See the answers to this question
  3. Your string is effectively a constant, so the retain count is probably MAX_INT. But you shouldn't rely on that
Community
  • 1
  • 1
Stephen Darlington
  • 51,577
  • 12
  • 107
  • 152
1

See what beryllium said above ;) Never use -retainCount That said, there are two issues here:

The first isn't in the autorelease pool, but in your NSLog.

-[NSObject retainCount] returns an NSUInteger, which is either 32-bits wide or 64-bits wide, depending on the system architecture. It's considered best practice to always cast NSInteger values to (long) and NSUInteger values to (unsigned long) when a function takes a variable number of arguments. Hence:

NSLog(@"%l", (long)[str integerValue]

or

NSLog(@"%lu", (unsigned long)[str retainCount])

The second is an optimization: @"This is string object" is actually an NSString by itself, but a special NSString called a NSCFConstantString, which has a retain count of NSIntegerMax (meaning that they cannot be dealloc'd).

I just ran your original example, and it looks like an NSString initialized via -initWithString: returns the original string. In this case, that's the constant string, so it's returning NSIntegerMax.

iccir
  • 5,078
  • 2
  • 22
  • 34
-2

Just change %lu to %d

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

    NSString *str = [[NSString alloc]initWithString:@"This is string object"];
    NSLog(@"%d", [str retainCount]);
    [pool drain];


    return 0;
}
Sanjeev Rao
  • 2,247
  • 1
  • 19
  • 18
  • 3
    1) `retainCount` returns an `NSUInteger`, so the `%lu` is the correct specifier. 2) You should never evaluate `retainCount`. 3) Because in this case, `NSString` will simply optimize itself away and return the *constant* (unreleaseable) string `@"This is string object"` instead of a new object which thus returns a very high number for `retainCount`. – DarkDust Feb 01 '12 at 12:24