Objective c 如何重置某些对象';属性的初始值?
假设我有一个“dog”类的对象“dog”,其属性可以分为两组: (A) 分配dog时,只能初始化一次的属性Objective c 如何重置某些对象';属性的初始值?,objective-c,Objective C,假设我有一个“dog”类的对象“dog”,其属性可以分为两组: (A) 分配dog时,只能初始化一次的属性 (B) 必须每隔一段时间重新初始化(重置)一次的属性 所以我需要一个方法“resetB”,它使用self重置组(B)中的属性,即 -(void) resetB { self.propB1 = initValB1; self.propB2 = initValB2; self.propB3 = initValB3; } 为了避免重复代码(实际情况要复杂得多,有几十个属
(B) 必须每隔一段时间重新初始化(重置)一次的属性 所以我需要一个方法“resetB”,它使用self重置组(B)中的属性,即
-(void) resetB {
self.propB1 = initValB1;
self.propB2 = initValB2;
self.propB3 = initValB3;
}
为了避免重复代码(实际情况要复杂得多,有几十个属性),我想从我的“init”调用“resetB”,使init wuld看起来像这样
-(id) init {
self = [super init];
if ( self ) {
propA1 = initValA1;
propA2 = initValA2;
propA3 = initValA3;
[self resetB];
}
return self;
}
好的,但现在我担心我正在通过我的“init”方法传递“self”,人们说这是被考虑的。。。“不礼貌”。。。(可以这么说)。我的问题是:我是否过于担心礼仪问题,而实际上按照上述方式做是安全的?或者,也许,重复代码(必须保持同步)是较小的罪恶?或者还有另一种“正确”的方法吗?我认为从
init
内部调用self
上的方法被认为是潜在危险的唯一原因是当您调用属性设置器或KVO可能导致副作用的另一种方法时
如果您知道该方法不会引起副作用,那么调用它是安全的,并且从多个版本的init
或awakeFromNib
等调用一个常见的“设置方法”是非常正常的
EDIT正如@sergio所提到的,避免从init
对self
调用方法的另一个原因是它可能被未正确初始化的子类覆盖。解决这个问题的一种方法是将重置实现放在一个私有方法中,该方法从init
调用,并让公共方法也使用私有方法。虽然私有方法也可以被覆盖,但显然它不应该被覆盖:
@interface MyClass ()
- (void)_resetB;
@end
@implementation MyClass
-(id) init {
self = [super init];
if ( self ) {
_propA1 = initValA1;
_propA2 = initValA2;
_propA3 = initValA3;
[self _resetB];
}
return self;
}
- (void)resetB
{
[self _resetB];
}
#pragma mark - Private Methods
- (void)_resetB
{
_propB1 = initValB1;
_propB2 = initValB2;
_propB3 = initValB3;
}
@end
当满足以下两个条件时,从
init
向self
发送消息是安全的:
- 您正在调用的方法不会被派生类覆盖——在这种情况下,派生类实现将在对象完全初始化之前被调用
- 您没有设置属性,该属性可能会通过KVO触发同一对象上的某些操作(该对象仍然未完全初始化)
reset
方法(与设置属性无关)是私有的,则应该没有问题,除非有人在派生类中定义了同名的方法
为了进一步降低这种风险,您可以为您的私有方法使用命名约定,例如,
\u resetB
使用init
方法向self
发送消息是完全安全的。你在哪里听到别的?你可能听说过不要泄露自己。这是不同的。根据我的经验,如果我看到有人直接设置属性(不使用属性设置器)。我想这一定是有原因的。即使是在init方法中。@CrimsonChris,谢谢你的评论。我“听说不是这样”的地方是developer.apple.com。它说:“你应该总是直接从初始化方法中访问实例变量,因为……”你可以很容易地找到相关的网页。我更喜欢从不使用KVO(这是邪恶的),而只是让自定义设置为零安全。这比用nil检查自己的init方法更简单。这并不完全正确。风险还在于调用派生类中重写的方法;在这种情况下,派生类实现将在一个未完全初始化的对象内执行。@sergio Yeah这会导致问题,调用私有方法肯定会更安全(并且让公共方法调用私有方法),正如您在回答中所建议的,最终它归结为与KVO相同的问题。我唯一不明白的是谁否决了我的答案。。。但很高兴看到你在现场找到它!谢谢。@sergio看起来上下两位选民对我们的答案都改变了主意。是时候继续做一些有意义的事情了,比如说现实生活:)谢谢,你和@trojanfoe的答案都非常清楚和有用。我对objc(以及总体上的OO)相当陌生,有时我感觉到“模糊的不可触及的层”的存在,这让我想回到汇编语言……:)