Amazon.com Widgets Program 19.5 Why retain an NSString when it holds a constant string object?
Welcome, Guest. Please login or register.
Did you miss your activation email?
October 23, 2014, 10:51:03 AM
Home Help Search chat Login Register 
News: Read this please.The Great Kangaroo Escape Looking for reviews of the 4th ed on Amazon!   Twitter:  @skochan
                     

+ Official Forum for Programming in Objective-C (the iPhone Programming Language) - Stephen Kochan
|-+ Old Stuff
| |-+ Chapter Study
| | |-+ Chapter 19 - Archiving
| | | |-+ Program 19.5 Why retain an NSString when it holds a constant string object?
Pages: [1] Go Down
Print
Author Topic: Program 19.5 Why retain an NSString when it holds a constant string object? (Read 1020 times)
fav321
Newbie
*
Posts: 8


Email




on: January 06, 2012, 08:50:33 AM

   
Code: (Objective-C)
 -(id) initWithCoder: (NSCoder *) decoder  
    { 
       name = [[decoder decodeObjectforKey: @"AddressCardName"] retain]; 
       email = [[decoder decodeObjectforKey: @"AddressCardEmail"] retain]; 
     
       return self; 
    } 

Since the instance variables 'name' and 'email' are NSStrings why are we worried about retaining them?

Here is a line from chapter 17...

Constant strings use no reference-counting mechanism because they can never be
released.This is why when the retainCount message is sent to myStr1, it returns a value
of 0xfffffffffffffff.


Any ideas?
Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #1 on: January 06, 2012, 09:30:58 AM

The values that are returned by the decoder methods are autoreleased and so must be retained (this is critical for an iOS app).   By the time these values have been archived and unarchived they're no longer "constant" string objects.

Cheers,

Steve
Logged
fav321
Newbie
*
Posts: 8


Email




Reply #2 on: January 06, 2012, 02:21:07 PM

Thanks Steve.

I was under the understanding that an NSString object was always a Constant Character String but after some testing I've realized that is not the case.

As in the following code example.

Code: (Objective-C)
int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString *str1 = @"String One";
NSString *str2 = [NSString stringWithCString: (char *)"hello"];
NSString *str3 = [[NSString alloc] initWithString: @"String 3"];
NSString *str4 = [NSString stringWithFormat: @"%s and %i", (char *)"Happy New Year ", 2012];

NSLog(@"str1: Retain Count: %lx", [str1 retainCount]);
NSLog(@"str2: Retain Count: %lx", [str2 retainCount]);
NSLog(@"str3: Retain Count: %lx", [str3 retainCount]);
NSLog(@"str4: Retain Count: %lx", [str4 retainCount]);

[pool drain];
    return 0;
}

Produces the following output:

[Session started at 2012-01-06 15:02:51 -0600.]
2012-01-06 15:02:51.537 Practice[4069:10b] str1: Retain Count: 7fffffff
2012-01-06 15:02:51.559 Practice[4069:10b] str2: Retain Count: 1
2012-01-06 15:02:51.568 Practice[4069:10b] str3: Retain Count: 7fffffff
2012-01-06 15:02:51.571 Practice[4069:10b] str4: Retain Count: 1


So depending how the NSString object was created will determine whether or not it is treated as a Constant Character String Object.

It is interesting to note that even though str3 was created using alloc and init that it still doesn't need to be released.

Thanks for the help. Great book by the way.
Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #3 on: January 07, 2012, 01:39:55 PM

Any alloc'ed object should still be released.  You are relying on the underlying implementation details, which are not documented and are subject to change.  So it's safest to always follow the rule of releasing any object you create with alloc, copy, mutableCopy, or new.

Cheers,

Steve
Logged
Pages: [1] Go Up
Print
Jump to:



Login with username, password and session length

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Entire forum contents (c) 2009 classroomM.com. All rights reserved.