3

我总是看到人们争论是否在-init方法中使用属性的设置器。我的问题是如何在子类中为继承的属性创建默认值。假设我们有一个名为的类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 新手要做什么呢?好吧,我的意思是,我只能做一件事,那就是设置属性。除非我错过了什么。有什么想法、建议、提示或技巧吗?

4

2 回答 2

3

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

考虑常见和一般情况:您想将您transform的设置为UIView子类。除了 call ,你会如何解决这个问题setTransform:?子类化非 Apple 代码也不例外。

于 2014-05-30T18:08:40.137 回答
0

使其成为@protected。如今,将 ivar 或财产私有化是非常罕见的。在实现中更好地声明私有 ivars 和/或属性。就此而言,@protected ivars/properties 在 Objective-C 中很少见,但非常好。

如果您想使用 setter/getter 声明属性,则使用 setter 作为方法或使用点表示法都是错误的(是的,它可以工作,但形式很糟糕)。

于 2014-05-30T03:16:59.003 回答