在Objective-C中覆盖延迟加载的属性getter

Goo*_*rel 7 overriding lazy-loading properties objective-c lazy-initialization

我通常懒惰地在他们的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;
}
Run Code Online (Sandbox Code Playgroud)

但是当子类化时,我经常想要覆盖一些@properties以使其更具子类.所以我想改变实例化并执行以下操作:

@interface MySpecificSubclass : MyGenericClass
//...

@implementation MySpecificSubclass

- (UIImageView *)infoImageView
{
    if (!_infoImageView) {
        _infoImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"SpecialInfoImage"]];
    }
    return _infoImageView;
}
Run Code Online (Sandbox Code Playgroud)

但那是不可能的,因为子类无法访问_infoImageView iVar.

我正在努力做坏事吗?或者有一个共同的解决方案/最佳实践吗?我看到的唯一解决方案是让iVar公开,这感觉违反了封装原则......

感觉这是一个非常基本的问题,那里必须有数百万的答案,但是在搜索了几个小时之后,我发现的一切都是Objective-C:当覆盖超类getter并尝试访问ivar时编译错误 ,但是它没有解决方案.

dar*_*iaa 9

您可能希望_infoImageView在头文件中与属性一起声明为受保护变量.另一个想法是创建一个公共defaultImageView方法来调用惰性getter.像这样的东西:

@interface MyGenericClass : UIViewController
@property (nonatomic, readonly) UIImageView *infoImageView
Run Code Online (Sandbox Code Playgroud)

...

@implementation GenericClass

- (UIImageView *)infoImageView
{
    if (!_infoImageView) {
        _infoImageView = [self defaultImageView];
    }
    return _infoImageView;
}

- (UIImageView *)defaultImageView
{
    return [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"PlaceholderInfoImage"]];
}
Run Code Online (Sandbox Code Playgroud)

...

@interface MySpecificSubclass : MyGenericClass
Run Code Online (Sandbox Code Playgroud)

...

@implementation MySpecificSubclass

- (UIImageView *)defaultImageView
{
    return [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SpecialInfoImage"]];
}
Run Code Online (Sandbox Code Playgroud)