在不使用访问者的情况下为继承的属性设置默认值

时间:2014-05-30 02:48:05

标签: objective-c subclass accessor ivar declared-property

我总是看到人们争论是否在-init方法中使用属性的setter。我的问题是如何在继承属性的子类中创建默认值。假设我们有一个名为NSLawyer的类 - 一个框架类,我无法改变 - 使用如下所示的接口:

@interface NSLawyer : NSObject {
    @private
    NSUInteger _numberOfClients;
}

@property (nonatomic, assign) NSUInteger numberOfClients;

@end

一个看起来像这样的实现:

@implementation NSLawyer

- (instancetype)init
{
    self = [super init];
    if (self) {
        _numberOfClients = 0;
    }
    return self;
}

@end

现在让我们说我想扩展NSLawyer。我的子类将被称为SeniorPartner。由于高级合作伙伴应该拥有大量客户端,因此在初始化SeniorPartner时,我不希望实例以0开头;我希望它有10。这是SeniorPartner.m:

@implementation SeniorPartner

- (instancetype)init
{
    self = [super init];
    if (self) {

        // Attempting to set the ivar directly will result in the compiler saying, 
        // "Instance variable _numberOfClients is private."

        // _numberOfClients = 10; <- Can't do this.

        // Thus, the only way to set it is with the mutator:
        self.numberOfClients = 10;

        // Or: [self setNumberOfClients:10];
    }
    return self;
}

@end

那么什么是Objective-C新人呢?嗯,我的意思是,我只能做一件事,那就是设置属性。除非有我遗漏的东西。任何想法,建议,提示或技巧?

2 个答案:

答案 0 :(得分:3)

你应该完全拥有;打电话给访问者。声明类通常避免在init中调用自己的访问器,以避免在子类中意外调用被覆盖的访问器,这可能依赖于尚未初始化的数据的一致性。另一方面,超类应该在子类运行init时完全一致,因此在那时使用超类访问器没有问题。

考虑常见和一般情况:您希望在transform子类中设置UIView。除了致电setTransform:之外,你会如何解决?对非Apple代码进行子类化也不例外。

答案 1 :(得分:0)

让它@protected。这些天很难将伊塔尔或财产私有化。私有ivars和/或属性在实现中更好地声明。就此而言,在Objective-C中很少见到@protected ivars / properties,但完全没问题。

使用setter作为方法或使用点符号是错误的(是的,它可以工作但是形式非常糟糕),如果你想使用setter / getters声明属性。