使用特定类型覆盖UIViewController.view

Jas*_*ues 4 cocoa-touch objective-c ios

让我们考虑具有高度自定义或复杂视图的应用程序.

我们将有一种特定类型的视图控制器发送方法到特定类型的UIView,其中UIView本身由许多其他视图组成.

该视图应具有丰富的特定于域的界面,允许控制器在其与类似的丰富模型之间进行操作.

所以我们覆盖控制器的view属性,如下所示:

@interface PlaybackViewController : UIViewController<StageLayoutDelegate, ControlPanelDelegate>
{
    NSMutableArray* _sections;
    LightingMode _lightingMode;
}

@property (nonatomic, strong) PlaybackView* view; // <------ Specific type of view

#pragma mark - injected
@property (nonatomic, strong) id<OscClient> oscClient;
@property (nonatomic, strong) AbstractStageLayoutView* stageLayoutView;

@end
Run Code Online (Sandbox Code Playgroud)

Ovverriding对于定义另一个访问器是有意义的,我只需将消息发送到特定类型的UIView而无需强制转换.

问题:唯一的问题是它会导致编译器警告:

属性类型'PlaybackView*'与从'UIViewController'继承的类型'UIView*'不兼容

..我喜欢构建没有任何警告的代码.这样,有效的警告不会被埋没在其他警告之中.

题:

  • 有没有办法压制这个特别的警告?
  • 当大多数现代OO语言很乐意允许覆盖子类中的属性或方法以便它返回超类中声明的类型的更具体的子类时,为什么这是默认设置的一部分?

War*_*ton 7

这里的问题不是覆盖属性,而是使用类类型的前向声明.

所以这...

@class PlaybackView;

@interface PlaybackViewController : UIViewController

@property (nonatomic, strong) PlaybackView* view;

@end
Run Code Online (Sandbox Code Playgroud)

会给你提到上面提到的警告,因为编译器无法知道继承层次结构PlaybackView.UIViewController有合同提供UIViewview财产

它告诉你它认为PlaybackView不是一个UIView

这里的简单解决方案是使用a #import代替给编译器充分了解PlaybackView...

#import "PlaybackView.h"

@interface PlaybackViewController : UIViewController

@property (nonatomic, strong) PlaybackView* view;

@end
Run Code Online (Sandbox Code Playgroud)

或者(但由于PCH是一种优化功能并且不应该管理依赖性,因此形式非常糟糕)是添加#import "PlaybackView.h"到您的项目PCH