在Objective-C中使用延迟加载重写属性getter
我通常在@property对象的getter方法中懒洋洋地实例化它们,如下所示:在Objective-C中使用延迟加载重写属性getter,objective-c,properties,overriding,lazy-loading,lazy-initialization,Objective C,Properties,Overriding,Lazy Loading,Lazy Initialization,我通常在@property对象的getter方法中懒洋洋地实例化它们,如下所示: @interface MyGenericClass : UIViewController @property(nonatomic, readonly) UIImageView *infoImageView // ... @implementation GenericClass - (UIImageView *)infoImageView { if (!_infoImageView) {
@interface MyGenericClass : UIViewController
@property(nonatomic, readonly) UIImageView *infoImageView
// ...
@implementation GenericClass
- (UIImageView *)infoImageView
{
if (!_infoImageView) {
_infoImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"PlaceholderInfoImage"]];
}
return _infoImageView;
}
@interface MyGenericClass : UIViewController
@property (nonatomic, readonly) UIImageView *infoImageView
但是,当子类化时,我经常希望重写一些@properties,使其更特定于子类。因此,我想更改实例化并执行以下操作:
@interface MySpecificSubclass : MyGenericClass
//...
@implementation MySpecificSubclass
- (UIImageView *)infoImageView
{
if (!_infoImageView) {
_infoImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"SpecialInfoImage"]];
}
return _infoImageView;
}
但这是不可能的,因为子类无法访问_infoimageviewivar
我想做的是不好的风格吗?
还是有一个通用的解决方案/最佳实践?我看到的唯一解决方案是公开iVar,这感觉像违反了封装原则
感觉这是一个非常基本的问题,肯定有数以百万计的答案,但经过几个小时的搜索,我只能找到
,但它没有提供解决方案。您可能希望将
\u infoImageView
与属性一起声明为头文件中的受保护变量。
另一个想法是创建一个publicdefaultImageView
方法来在lazy getter内部调用。
大概是这样的:
@interface MyGenericClass : UIViewController
@property(nonatomic, readonly) UIImageView *infoImageView
// ...
@implementation GenericClass
- (UIImageView *)infoImageView
{
if (!_infoImageView) {
_infoImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"PlaceholderInfoImage"]];
}
return _infoImageView;
}
@interface MyGenericClass : UIViewController
@property (nonatomic, readonly) UIImageView *infoImageView
您可以使用
UIViewController
用于其视图的技术:
- (UIView *)view{
if(!_view){
[self loadView];
NSAssert(_view, @"View must be set at end of loadView");
}
return _view;
}
- (void)loadView{
// subclasses must set self.view in their override of this.
NSAssert(NO, @"To be overridden by subclass");
}
- (UIView *)view{
if(!_view){
[self loadView];
NSAssert(_view, @"View must be set at end of loadView");
}
return _view;
}
- (void)loadView{
// subclasses must set self.view in their override of this.
NSAssert(NO, @"To be overridden by subclass");
}