Objective-c-NSMutableString设置字符串与NSString
在setter中,按如下方式保留和释放NSString是否是更好的做法:Objective-c-NSMutableString设置字符串与NSString,objective-c,nsstring,release,retain,nsmutablestring,Objective C,Nsstring,Release,Retain,Nsmutablestring,在setter中,按如下方式保留和释放NSString是否是更好的做法: -(void) setName:(NSString *)newName { if(newName != nil) { [newName retain]: [m_Name release]; m_Name = newName; //Where m_Name is a NSString * } //I'm not sure for this
-(void) setName:(NSString *)newName
{
if(newName != nil)
{
[newName retain]:
[m_Name release];
m_Name = newName; //Where m_Name is a NSString *
}
//I'm not sure for this code, I have difficulties understanding memory-management in ObjC
}
或通过NSMutableString更改值:
-(void) setName:(NSString *)newName
{
if(newName != nil)
[m_Name setString:newName]; //Where m_Name is a NSMutableString *
}
如果任何一种或两种方法都不正确,请告诉我。第一种解决方案更好。这就是
retain
属性的处理方式。保留新值,然后释放旧值。另外,如果要处理的nil
情况并不重要,则可以依赖于由@synthesis
生成的默认实现
对于第二种解决方案,它确实是不必要的,而且有点违反惯例。此外,在这个解决方案中,您必须在为其分配任何字符串之前初始化m_name
。您可以在init
中执行此操作
- (void) init {
if (self = [super init]) {
m_name = [[NSMutableString alloc] init];
}
}
结论:第一种解决方案肯定更好。第一种解决方案更好。这就是
retain
属性的处理方式。保留新值,然后释放旧值。另外,如果要处理的nil
情况并不重要,则可以依赖于由@synthesis
生成的默认实现
对于第二种解决方案,它确实是不必要的,而且有点违反惯例。此外,在这个解决方案中,您必须在为其分配任何字符串之前初始化m_name
。您可以在init
中执行此操作
- (void) init {
if (self = [super init]) {
m_name = [[NSMutableString alloc] init];
}
}
结论:第一种解决方案肯定更好。一些想法:
name
的属性,ivar是\u name
)。如果省略@synthesis
语句,最新版本的Xcode附带的编译器将自动为您执行此操作retain
NSMutableString
会更改属性的行为,我不建议您这样做,除非您出于某种原因确实需要可变字符串name
属性设置为nil
,则第一个示例不会执行任何操作。但是如果有人想将其设置为nil
,您仍然应该(a)释放旧的name
值;和(b)将ivar设置为nil
。(顺便说一句,我下面的代码利用了这样一个事实,即向nil
对象发送消息没有任何作用,因此在这种情况下,我不需要检查它是否为nil
)@property (nonatomic, retain) NSString *name;
一条合成线被省略或看起来像:
@synthesize name = _name;
然后,我想二传手会是这样的:
-(void) setName:(NSString *)name
{
// if you want to program defensively, you might want the following assert statement:
//
// NSAssert(name == nil || [name isKindOfClass:[NSString class]], @"%s: name is not string", __FUNCTION__);
if (name != _name)
{
[_name release];
_name = name;
[_name retain];
}
}
-(void) setName:(NSString *)name
{
// if you want to program defensively, you might want the following assert statement:
//
// NSAssert(name == nil || [name isKindOfClass:[NSString class]], @"%s: name is not string", __FUNCTION__);
if (name != _name)
{
[_name release];
_name = [name copy];
}
}
顺便说一下,我假设您的init
方法正确地初始化了\u name
,并且dealloc
释放了它
- (id)init
{
self = [super init];
if (self) {
_name = nil;
}
return self;
}
- (void)dealloc
{
[_name release];
[super dealloc];
}
正如bblum所指出的,谨慎的做法是对
NSString
属性使用copy
:
@property (nonatomic, copy) NSString *name;
然后,我想二传手会是这样的:
-(void) setName:(NSString *)name
{
// if you want to program defensively, you might want the following assert statement:
//
// NSAssert(name == nil || [name isKindOfClass:[NSString class]], @"%s: name is not string", __FUNCTION__);
if (name != _name)
{
[_name release];
_name = name;
[_name retain];
}
}
-(void) setName:(NSString *)name
{
// if you want to program defensively, you might want the following assert statement:
//
// NSAssert(name == nil || [name isKindOfClass:[NSString class]], @"%s: name is not string", __FUNCTION__);
if (name != _name)
{
[_name release];
_name = [name copy];
}
}
但实际上,你不应该写二传,除非你绝对需要
最后,您的代码有一条评论,指出内存管理令人困惑。虽然你肯定需要理解它,但我还是要提出最后两个建议:
name
的属性,ivar是\u name
)。如果省略@synthesis
语句,最新版本的Xcode附带的编译器将自动为您执行此操作retain
NSMutableString
会更改属性的行为,我不建议您这样做,除非您出于某种原因确实需要可变字符串name
属性设置为nil
,则第一个示例不会执行任何操作。但是如果有人想将其设置为nil
,您仍然应该(a)释放旧的name
值;和(b)将ivar设置为nil
。(顺便说一下,我下面的代码利用了