Žel*_*ber 5 initialization objective-c init nsstring nscopying
我有两个问题.
首先 - 在obj-c中声明字符串
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *city;
Run Code Online (Sandbox Code Playgroud)
那些是(nonatomic, copy)正确的还是应该使用(nonatomic, strong),还是其他什么?
第二 - 如果我想为上面的字符串设置自定义初始值设定器,我会使用
-(id)initWithName:(NSString *)n andCity:(NSString *)c
{
self = [super init];
if (self) {
self.name = n;
self.city = c;
}
}
Run Code Online (Sandbox Code Playgroud)
或者我应该使用:
-(id)initWithName:(NSString *)n andCity:(NSString *)c
{
self = [super init];
if (self) {
self.name = [n copy]
self.city = [c copy];
}
}
Run Code Online (Sandbox Code Playgroud)
我可以看到两种方式似乎都适用于这两个问题,但我确信一个方法比另一个方法更正确,所以我想问一下我应该用哪些方法在其他项目中编写正确的代码.
谢谢.
ipm*_*mcc 11
您希望copy用于值语义类型的属性.(其中一个NSString总是一个.)否则,我可以通过你一个实例,NSMutableString然后在你之后将它从你下面改掉.不可变对象将-copyWithZone:通过执行来实现return [self retain]; 以便在不需要时不会实际创建第二个副本.另请参见:NSString属性:复制还是保留?
就您的-init方法而言,您希望避免使用属性设置器,因为它们可以在子类中重写,以执行您的类无法预见的操作.因此,假设默认的auto-ivar-synthesis命名模式,您可能希望这样做:
-(id)initWithName:(NSString *)n andCity:(NSString *)c
{
if (self = [super init])
{
_name = [n copy];
_city = [c copy];
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
这是一个微妙的事情,它通常不会成为一个问题,但如果你继续使用固有的虚拟属性设置器-init和-dealloc方法,在足够长的时间线上,你会被这个烧掉(你能说我一直都是烧这个?)
至于泄露的内存,如果你正在使用ARC,那么做一些事情就像self.foo = [bar copy];foo copy属性一样会导致副本被调用两次,并且可能会产生两个副本,但是ARC应该负责正确地释放冗余/中间副本,并且应该没有内存泄漏.