我通常懒惰地在他们的getter方法中实例化我的@property对象,如下所示:
@interface MyGenericclass : UIViewController
@property(nonatomic,readonly) UIImageView *infoImageView
// ...
@implementation Genericclass
- (UIImageView *)infoImageView
{
if (!_infoImageView) {
_infoImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"PlaceholderInfoImage"]];
}
return _infoImageView;
}
但是当子类化时,我经常想要覆盖一些@properties以使其更具子类.所以我想改变实例化并执行以下操作:
@interface MySpecificSubclass : MyGenericclass
//...
@implementation MySpecificSubclass
- (UIImageView *)infoImageView
{
if (!_infoImageView) {
_infoImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"SpecialInfoImage"]];
}
return _infoImageView;
}
但那是不可能的,因为子类无法访问_infoImageView iVar.
我正在努力做坏事吗?
或者有一个共同的解决方案/最佳实践吗?我看到的唯一解决方案是让iVar公开,这感觉违反了封装原则……
感觉这是一个非常基本的问题,那里必须有数百万的答案,但在搜索了几个小时之后我才发现它是Objective-C: Compiler error when overriding a superclass getter and trying to access ivar
,但它没有提供解决方案.
解决方法
您可能希望将_infoImageView声明为头文件中的受保护变量以及属性.
另一个想法是创建一个公共defaultimageView方法来调用惰性getter.
像这样的东西:
另一个想法是创建一个公共defaultimageView方法来调用惰性getter.
像这样的东西:
@interface MyGenericclass : UIViewController @property (nonatomic,readonly) UIImageView *infoImageView
…
@implementation Genericclass
- (UIImageView *)infoImageView
{
if (!_infoImageView) {
_infoImageView = [self defaultimageView];
}
return _infoImageView;
}
- (UIImageView *)defaultimageView
{
return [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"PlaceholderInfoImage"]];
}
…
@interface MySpecificSubclass : MyGenericclass
…
@implementation MySpecificSubclass
- (UIImageView *)defaultimageView
{
return [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SpecialInfoImage"]];
}