我总是看到人们争论是否在-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新人呢?嗯,我的意思是,我只能做一件事,那就是设置属性。除非有我遗漏的东西。任何想法,建议,提示或技巧?
答案 0 :(得分:3)
你应该完全拥有;打电话给访问者。声明类通常避免在init
中调用自己的访问器,以避免在子类中意外调用被覆盖的访问器,这可能依赖于尚未初始化的数据的一致性。另一方面,超类应该在子类运行init
时完全一致,因此在那时使用超类访问器没有问题。
考虑常见和一般情况:您希望在transform
子类中设置UIView
。除了致电setTransform:
之外,你会如何解决?对非Apple代码进行子类化也不例外。
答案 1 :(得分:0)
让它@protected。这些天很难将伊塔尔或财产私有化。私有ivars和/或属性在实现中更好地声明。就此而言,在Objective-C中很少见到@protected ivars / properties,但完全没问题。
使用setter作为方法或使用点符号是错误的(是的,它可以工作但是形式非常糟糕),如果你想使用setter / getters声明属性。