复制变量名称

时间:2015-06-23 03:03:28

标签: objective-c

<code>
//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

<code>

所以我在堆栈溢出上看到了这个代码,这不是我的代码,我不是想接受它,或者我只是对目标C中的这段代码有一个快速的问题。在(void) setName: (NSString *) theName方法中为什么我们必须[name release]然后name = [[NSString alloc] initWithString: theName]

为什么我们不能简单地说name = theName。这不会只是将theName方法中作为参数传递的setName变量复制到原始name变量中吗?

很抱歉,如果这是一个糟糕的问题,但我是目标c的新手,对来自java背景的内存管理有点困惑。

1 个答案:

答案 0 :(得分:2)

正确的现代风格是在项目中使用ARC(自动引用计数),这是新项目的默认设置(已经有几年了)。然后,您不需要也不允许发送release消息。

initWithString:stringWithString:的选择在ARC下没有任何区别,您也可以这样写出来:

- (void)setName:(NSString *)theName {
    name = [theName copy];
}

使用copy(或initWithString:stringWithString:),即使来电者传入name,您也可以确保NSMutableString不会改变然后改变其内容。

但是如果你只想做你在问题中所做的事情,你可能甚至不需要写一个二传手。您需要做的就是将其放在.h文件中:

@interface AddressCard

@property (nonatomic, strong) NSString *name;

// other declarations...

@end

如果省略它们,编译器将自动生成一个实例变量(名为_name),一个setter和一个getter。但是,使用strong表示编译器生成的setter不会复制字符串;它只会保持对调用者给出的字符串的引用。

如果您想使用上面描述的copy,请改为声明属性:

@property (nonatomic, copy) NSString *name;

然后编译器将生成一个使用copy

的setter