请考虑以下两种初始化方法。
第一种方法只是将参数的值传递给它们各自的NSString属性,但第二种方法分配属性,然后使用initWithString:方法初始化它们。后一个例子中的分配是否必要?
提前致谢。
-(id)initWithTitle:(NSString *)theTitle muscleGroup:(NSString *)theMuscleGroup equipment:(NSString *)theEquipment {
if((self = [super init])){
title = theTitle;
muscleGroup = theMuscleGroup;
equipment = theEquipment;
}
return self;
}
-(id)initWithTitle2:(NSString *)theTitle muscleGroup:(NSString *)theMuscleGroup equipment:(NSString *)theEquipment {
if((self = [super init])){
title = [[NSString alloc] initWithString:theTitle];
muscleGroup = [[NSString alloc] initWithString:theMuscleGroup];
equipment = [[NSString alloc] initWithString:theEquipment];
}
return self;
}
答案 0 :(得分:5)
第一个示例并不安全,因为您没有获取字符串的所有权,因此如果稍后在其他地方发布,您的程序将会崩溃。第二个例子修复了这个问题,并且可以很好地工作,但是这样写得更简洁:
-(id)initWithTitle2:(NSString *)theTitle muscleGroup:(NSString *)theMuscleGroup equipment:(NSString *)theEquipment {
if((self = [super init])){
title = [theTitle copy];
muscleGroup = [theMuscleGroup copy];
equipment = [theEquipment copy];
}
return self;
}
NSString为您提供了一个复制构造函数(-initWithString:
),它使您能够在#2中执行您正在执行的操作,但并非所有类都执行此操作。 copy
要求类实现NSCopying协议,但更符合Cocoa API开发人员期望能够复制对象的方式。
答案 1 :(得分:2)
传递参数对象时不会复制它们。因此,您的第一个示例可能并不总是有效,这取决于您初始化字符串的方式。
以下更安全(尽管记得在dealloc方法中释放对象):
-(id)initWithTitle:(NSString *)theTitle muscleGroup:(NSString *)theMuscleGroup equipment:(NSString *)theEquipment {
if((self = [super init])){
title = [theTitle retain];
muscleGroup = [theMuscleGroup retain];
equipment = [theEquipment retain];
}
return self;
}
答案 2 :(得分:2)
示例1将分配指针。它不会试图保留对象,并且容易受到改变对象内容之外的东西的影响。
它可以起作用取决于参数的构造方式;
示例2将复制字符串对象并保留它们。只要您在dealloc中释放,那么它就是更好的方法。
FWIW
title = [theTitle copy];
或
title = [[NSString stringWithString:theTitle] retain];
在Ex 2中同样出色