Objective c NSString属性和自定义初始化
我有两个问题 首先-字符串在obj-c中声明为Objective c NSString属性和自定义初始化,objective-c,nsstring,initialization,init,nscopying,Objective C,Nsstring,Initialization,Init,Nscopying,我有两个问题 首先-字符串在obj-c中声明为 @property (nonatomic, copy) NSString *name; @property (nonatomic, copy) NSString *city; 那些(非原子,复制)是正确的还是我应该使用(非原子,强),或者其他什么 Second-如果我想为上述字符串设置自定义初始值设定项,我应该使用吗 -(id)initWithName:(NSString *)n andCity:(NSString *)c { self
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *city;
那些(非原子,复制)
是正确的还是我应该使用(非原子,强)
,或者其他什么
Second-如果我想为上述字符串设置自定义初始值设定项,我应该使用吗
-(id)initWithName:(NSString *)n andCity:(NSString *)c
{
self = [super init];
if (self) {
self.name = n;
self.city = c;
}
}
或者我应该使用:
-(id)initWithName:(NSString *)n andCity:(NSString *)c
{
self = [super init];
if (self) {
self.name = [n copy]
self.city = [c copy];
}
}
正如我所看到的,两种方法似乎都适用于两个问题,但我确信其中一种方法比另一种更正确,因此我想问,在以后的项目中,我应该使用哪种方法来编写正确的代码
谢谢。首先-使用
copy
或strong
并不重要。就我个人而言,我更喜欢复制字符串而不是保留它们
第二-`
-(id)initWithName:(NSString *)n andCity:(NSString *)c
{
self = [super init];
if (self) {
self.name = n;
self.city = c;
}
}`
您不需要再次使用
copy
消息,因为您的属性将复制n和c。如果应用第二段代码,您将复制n和c两次,并出现内存泄漏您希望对值语义类型属性使用copy
。(其中,NSString
始终是一个)否则,我可以向您传递一个NSMutableString
的实例,然后在事实发生后将其从您下面更改出来。不可变对象将通过执行返回[self-retain]
来实现-copyWithZone:
;这样就不会在不需要的时候创建第二个副本。另见:
就-init
方法而言,您希望避免像以前那样使用属性设置器,因为它们可以在子类中被重写,以执行类无法预见的操作。因此,假设默认的自动ivar合成命名模式,您需要执行以下操作:
-(id)initWithName:(NSString *)n andCity:(NSString *)c
{
if (self = [super init])
{
_name = [n copy];
_city = [c copy];
}
return self;
}
这是一件微妙的事情,通常不会成为问题,但如果您继续在-init
和-dealloc
方法中使用固有的虚拟财产设置器,在足够长的时间内,您会被这烧死(您能告诉我我被烧死了吗?)
至于泄漏的内存,如果您使用的是ARC,则执行类似于
self.foo=[bar copy]
当foo是copy
属性时,将导致copy被调用两次,并可能生成两个副本,但ARC应注意正确释放冗余/中间副本,并且不应出现内存泄漏。如果使用copy
与strong
相比,这非常重要。使用strong
我可以向您传递一个NSMutableString
的实例,然后在事后将其从您的下方更改出来。这就是为什么值语义属性应该始终是copy
。不可变对象将通过执行返回[self-retain]来实现-copyWithZone:
代码>以便在不需要时不实际创建第二个副本。