我正在使用 ARC。
这是我的 .h 文件
...
- (id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t;
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
...
这是我的 .m 文件
....
@synthesize coordinate, title;
- (id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t
{
self = [super init];
if (self) {
coordinate = c;
[self setTitle:t];
}
return self;
}
....
readonly
,似乎这是唯一的方法。如果我只使用默认值(即 readwrite
)怎么办,在这种情况下,我应该改用 setter 方法 [self setCoordinate] 吗? title = t
设置标题也是。与使用setter方法相比,结果是一样的,但有什么区别呢? 谢谢!希望我能接受你所有的答案。
最佳答案
您实际上应该一直直接在初始化方法中设置 ivars。无论您是否拥有 readonly
,这都是正确的。或 readwrite
属性(property)。 documentation here甚至这么说。
这背后的原因与继承有关。如果有人要对您的类进行子类化并覆盖您的属性的 setter ,以便他们绕过您创建的 ivars(或做一些其他古怪的事情),那么突然之间,您的初始化方法的原始实现现在不再执行其编写的操作.特别是,由于子类覆盖了您的访问器,您的初始化程序最终可能会创建一个具有奇怪状态的对象。在 ARC 之前的日子里,当这种事情发生时,你也可能会遇到棘手的(或者只是直接坏掉的)内存情况。要点是:您应该编写初始化程序,以便它们始终创建具有已知有效状态的对象。
因此(假设您使用的是 ARC)您的初始化程序实际上应该是:
- (id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t
{
self = [super init];
if (self) {
coordinate = c;
title = [t copy];
}
return self;
}
就个人而言,我更喜欢用下划线开始合成 ivars,以澄清我何时使用该属性以及何时直接访问该 ivar(LLVM 4.0 现在也这样做以自动合成属性)。
@synthesize coordinate = _coordinate;
@synthesize title = _title;
- (id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t
{
self = [super init];
if (self) {
_coordinate = c;
_title = [t copy];
}
return self;
}
关于 Objective-C : Need advice on setting instance variables in init method,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13104172/