除非有明确的原因需要使用
setter, getter
, 否则总是应该直接访问, 也就是直接使用实例变量(也称为iVar
)来读写数据
// 假设SQIPerson有一个子类叫做SQISmithPerson, 专门表示那些姓"Smith"的人, 重写了 lastName 属性对应的设置方法
- (void)setLastName:(NSString *)lastName {
if (![lastName isEqualToString:@"Smish"]) {
[NSException raise:NSInvalidArgumentException format:@"Last name must be Smith"];
}
[super setLastName:lastName]; // 使用super调用父类的setter方法, 而不是self.lastName = lastName;
}
属性的 setter 方法可能依赖于对象的其他部分:在 init 方法中,对象可能还没有完全初始化,依赖于对象其他部分的 setter 方法可能会引发错误或不一致的状态。
属性的 getter 和 setter 方法可能包含副作用:属性的 getter 和 setter 方法通常会做一些额外的工作,比如通知观察者、触发 KVO(Key-Value Observing)通知、或者执行自定义的逻辑。如果在初始化或销毁过程中使用这些方法,可能会导致一些未定义行为或者不必要的操作。
性能考虑:直接访问实例变量比通过属性访问更高效,因为它避免了方法调用的开销。在性能敏感的场合,尤其是在对象初始化和销毁过程中,直接访问实例变量可以提高性能。
在初始化方法中直接访问实例变量,可以确保初始化逻辑的简单和明确,不会受到继承层次结构中的其他因素影响。
@interface MyClass : NSObject
@property (nonatomic, strong) NSString *propertyName;
@end
@implementation MyClass
- (instancetype)init {
self = [super init];
if (self) {
_propertyName = @"initialValue"; // 直接访问实例变量
}
return self;
}
@end
在这个例子中,_propertyName
是实例变量,直接访问它可以避免调用任何潜在的子类重写的setter方法。
setter, getter
?同 init 方法, 建议: 除非有明确的原因需要使用setter, getter
, 否则总是应该直接访问