Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
398 views
in Technique[技术] by (71.8m points)

objective c - Object ownership in stringWithString and initWithString in NSString

I understand that any init... method initializes a new object and that NSString stringWithString makes a copy of the parameter string as a new object. I also understand that being the objects' owner, I can control the release/deallocation of any objects that I allocate. What I don't understand is when would I use the stringWithString method since any local variable assigned that way would have it's memory "owned" by NSString instead of the local class.

The "Programming in Objective C" book by Kochan (1st ed) uses the following code (see pages 342-344) to explain that the initWithString is preferable to stringWithString because the AddressCard class would own the name variable contents. Also, I don't get any errors making repeated calls to the setName version with the stringWithString method. TIA!!

//header file has appropriate declarations but not included here:
#import "AddressCard.h"

@implementation AddressCard;

-(NSString *) name
{
   return name;
}

//Recommended code:
-(void) setName: (NSString *) theName
{
   [name release]
   name = [[NSString alloc] initWthString: theName];
}

//Incorrect code according to Kochan:
-(void) setName: (NSString *) theName
{
   [name release]
   name = [NSString stringWthString: theName];
}

//rest of class implementation code snipped
@end
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

What I don't understand is when would I use the stringWithString method since any local variable assigned that way would have it's memory "owned" by NSString instead of the local class.

What? No.

The rules are simple:

  • Any object returned by alloc, copy, copyWithZone, or new has a retain count of 1.
  • retain increases the receiving object's retain count.
  • release decreases the receiving object's retain count.
  • autorelease tells the current autorelease pool to send the receiving object the release message “later”.
  • Any factory method that doesn't have “new” or “copy” in the name (e.g., stringWithString:) returns an object that it has autoreleased on your behalf.

Or, digested a bit:

  • Any method whose name contains copy, alloc, retain, or new returns an object that you own.
  • Any method that doesn't, returns an object that you don't own.
  • To own an object, retain it.

The incorrect implementation of setName: that you show is incorrect because it stores an autoreleased object in an instance variable, when you mean to own the object. You should retain it or, in this case, copy it. One way is to simply use alloc and initWithString:, as in the correct example you show; the other way would be copy.

The Memory Management Programming Guide for Cocoa explains everything. Every Cocoa or Cocoa Touch programmer should read or re-read it from time to time.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...