我知道任何init ...方法都会初始化一个新对象,并且NSString stringWithString会将参数字符串的副本作为新对象.我也理解作为对象的所有者,我可以控制我分配的任何对象的释放/释放.我不明白的是什么时候我会使用stringWithString方法,因为任何以这种方式分配的局部变量都会让它的内存由NSString而不是本地类"拥有".
Kochan的"Objective in Objective C"一书(第1版)使用以下代码(参见第342-344页)来解释initWithString比stringWithString更可取,因为AddressCard类将拥有名称变量contents.另外,使用stringWithString方法重复调用setName版本时,我没有任何错误.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
Run Code Online (Sandbox Code Playgroud)
Pet*_*sey 27
我不明白的是什么时候我会使用stringWithString方法,因为任何以这种方式分配的局部变量都会让它的内存由NSString而不是本地类"拥有".
什么?没有.
规则很简单:
alloc
,copy
,copyWithZone
,或new
具有为1的保留计数.retain
增加接收对象的保留计数.release
减少接收对象的保留计数.autorelease
告诉当前自动释放池向接收对象发送release
消息"稍后".stringWithString:
)返回一个代表您自动释放的对象.或者,消化了一下:
copy
,alloc
,retain
,或new
返回你自己的对象.setName:
您显示的错误实现是不正确的,因为它将一个自动释放的对象存储在实例变量中,当您意味着拥有该对象时.你应该保留它,或者在这种情况下,复制它.一种方法是简单地使用,alloc
并且initWithString:
如您所示的正确示例; 另一种方式copy
.
Cocoa的内存管理编程指南解释了一切.每个Cocoa或Cocoa Touch程序员都应该不时阅读或重新阅读.
实际上,两个人都错了.由于一般的内存管理原因(其他地方已经很好地阐述),"错误的"错误."推荐"的错误有两个原因:
'正确'(恕我直言)方法是:
-(void) setName: (NSString *) theName
{
if (theName == name) return; // if they're equal, no need to do anything further
[name release];
name = [theName copy]; // sets name to nil if theName is nil
}
Run Code Online (Sandbox Code Playgroud)
对于大多数对象,你实际上想要在第三行上获得而不是-copy,但对于字符串来说,复制几乎总是更好.