The length of the NSString and keepCount. Clarification required

Based on the following code, please inform

NSString *str= [[NSString alloc] initWithString:@"Hello world"]; NSLog(@"Length: %lu\n", [str length]); // 11 NSLog(@"Retain count is %lu\n", [str retainCount]); //1152921504606846975 [str release]; NSLog(@"%lu\n", [str length]); // 11 NSLog(@"Retain count is %lu\n", [str retainCount]); //1152921504606846975 
  • Initially, I was wondering why the number was so large, but then I saw a message explaining this . Let me ask about it instead ... Why is this number changing a lot if I use %d vs %lu . I originally used %d , but I got a warning saying that "Conversion is of type int, but the argument is of type NSUInteger (aka unsigned long). The fix was to change %d to %lu "

  • Why is the conservation decree not reduced? A large number is still displayed unchanged after sending str release

  • Why can I still access str after it was sent release ?

+4
source share
2 answers

This may be a difficult response to acceptance, but this is what you should do:

  • Do not worry about it. (from the point of view of% d /% lu, these specifiers simply expect different data types, and% d (int) has a much smaller and different range from% lu (unsigned long))
  • Do not worry about it.
  • Do not do this, and especially do not rely on it.

Perhaps this is due to the fact that you started with a constant line ( @"Hello world" ), that the memory is not freed when calling release, and keepCount is large. But if you need to take care of keepCount, you are doing it wrong.

You release the string in the right place, and this is important - never try to use it later.

+8
source

Ultimately, the behavior is determined by the implementation of NSString - just use keep / release correctly in each case and you will be safe.

what can happen: NSString literals are immortal. you can write while (1) { [@"String" release]; } while (1) { [@"String" release]; } and there will be no problems.

the ctor copy that you called most likely returns a pointer to a string literal. in pseudo code:

 - (id)initWithString:(NSString *)str { self = [super init]; if (self != nil) { if ([str _isStringLiteral] || [str _isImmutable]) { [self release]; return [str retain]; } ... } 

in this case, you are returned a pointer to a string literal when it passes through [[NSString alloc] initWithString:stringLiteral] . since sending release to an immortal string literal does nothing, you can understand why it is still a valid object, following what you might assume is a freed object.

never rely on such details / optimizations, just use normal lifetimes and reference counting and everything will be all right.

0
source

All Articles