9

我通常懒惰地在他们的 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 ,但是它没有提供任何解决方案。

4

2 回答 2

10

您可能希望_infoImageView与属性一起在头文件中声明为受保护的变量。另一个想法是创建一个公共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"]];
}
于 2013-10-09T15:30:39.523 回答
4

您可以使用UIViewController用于其的技术view

- (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");
}
于 2013-12-07T20:55:31.073 回答