如何将某些对象的属性重置为其初始值?

时间:2014-08-19 14:57:27

标签: objective-c

假设我有一个对象" dog"班级"狗"其属性可分为两组:

(A)在分配狗时必须初始化一次的属性;
 (B)必须每隔一段时间重新初始化(重置)的属性;

所以我需要一种方法" resetB"它使用self重置组(B)中的属性,即

-(void) resetB {
    self.propB1 = initValB1;
    self.propB2 = initValB2;
    self.propB3 = initValB3;
}

为了避免重复的代码(实际情况要复杂得多,有几十个属性),我想打电话给" resetB"来自我的" init",以便init wuold看起来像这样

-(id) init {
    self = [super init];
    if ( self ) {
        propA1 = initValA1;
        propA2 = initValA2;
        propA3 = initValA3;
        [self resetB];
    }
    return self;
}

好的,但现在我担心我会发短信" self"来自我的" init"方法,人们说被认为是......"不礼貌" ......(可以这么说) 我的问题是:我是否过分担心礼仪,如上所述实际上是安全的吗?或者,重复代码(必须保持同步)可能是较小的邪恶?或者还有另一个"正确"这样做的方式?

2 个答案:

答案 0 :(得分:2)

当符合两个条件时,从selfinit发送消息是安全的:

  • 您调用的方法不会被派生类覆盖 - 在这种情况下,派生类实现将在对象完全初始化之前调用;

  • 您没有设置属性,这可能会通过KVO触发对同一对象(仍未完全初始化)的某些操作。

如果您的reset方法(与设置属性无关)是私有的,那么它应该没有问题,除非有人在派生类中定义了一个具有相同名称的方法。

为了进一步降低此风险,您可以为私有方法使用命名约定,例如_resetB

答案 1 :(得分:1)

我认为,当您调用属性设置器或其他方法时,selfinit调用方法的唯一原因是有潜在危险 KVO可能引起副作用。

如果您知道该方法不会造成副作用,那么可以安全地拨打电话,并且调用常用的“安装方法”非常正常。来自多个版本的init或来自awakeFromNib等。

编辑正如@sergio所提到的,避免从self调用init上的方法的另一个原因是它可能会被未正确初始化的子类覆盖。另一种方法是将重置实现放入私有方法,该方法从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