【发布时间】:2023-03-26 03:25:01
【问题描述】:
在访问变量时,我倾向于在我的 Objective C 代码中经常使用 self.property,因为我知道这会使用 getter/setter 方法(显式编码或自动生成)。
另一位程序员最近告诉我,最好在整个代码中使用 _property。但我的理解是 _property 真的只用于 init 和 dealloc 方法。
今天我在一些使用 initWithCoder 的代码中发现了一个错误。我在 initWithCoder 方法中使用了 _property,不得不将其更改为 self.property。这是在设置 NSData 对象时。这是原始代码:
@property (nonatomic, strong) NSData *data;
- (id)initWithCoder:(NSCoder *)decoder {
self = [super init];
if (!self) {
return nil;
}
_data = [decoder decodeObjectForKey:@"data"];
return self;
}
我不得不把它改成这样,才能让它工作:
@property (nonatomic, strong) NSData *data;
- (id)initWithCoder:(NSCoder *)decoder {
self = [super init];
if (!self) {
return nil;
}
self.data = [decoder decodeObjectForKey:@"data"];
return self;
}
我的问题是 - 为什么 initWithCoder 是例外?如果普遍认为最好在 init 方法中使用 _property,那么为什么 initWithCoder 会有所不同?
现在看来,一般规则是:
使用 self.property,除了 init/dealloc 方法,应该使用 _property(除了 initWithCoder,应该使用 self.property)。
这是正确的吗?
【问题讨论】:
-
我看不出为什么在
initWithCoder:中你的代码self.property会在_property不起作用时起作用。self.property使用此属性的 setter 来初始化它是正确的,而_property并没有绕道而行,而是初始化了 instance 变量 直接属于你的财产......这看起来很奇怪:/ -
当你说“让它工作”时,你遇到了什么错误。我认为原始的基于 ivar 的 init 没有问题。告诉你只使用 ivars 的 coder 是不正确的;这不是最佳做法。曾经有一段时间在 ObjC 社区中存在更多分歧,但 Apple 终于记录了您应该使用除 init 和 dealloc 之外的访问器。
-
我刚刚做了一个测试,它适用于
_data和self.data。你的目标是什么版本的 iOS?更早的版本不会为属性data自动生成_data变量。 -
从initWithCoder返回时出现错误,而不是在initWithCoder中。我在 initWithCoder 中放了一个断点,对 _data 的分配没问题。问题发生在 [NSKeyedUnarchiver unarchiveObjectWithFile:cachePathForKey]; 之后陈述。当它从这里返回时,该对象包含垃圾,除非我使用 self.data 而不是 _data
-
应用的部署目标是7.0
标签: objective-c getter-setter initwithcoder