Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 使用特定类型覆盖UIViewController.view 让我们考虑一个具有高度定制或复杂视图的应用程序。p>_Ios_Objective C_Cocoa Touch - Fatal编程技术网

Ios 使用特定类型覆盖UIViewController.view 让我们考虑一个具有高度定制或复杂视图的应用程序。p>

Ios 使用特定类型覆盖UIViewController.view 让我们考虑一个具有高度定制或复杂视图的应用程序。p>,ios,objective-c,cocoa-touch,Ios,Objective C,Cocoa Touch,我们将有一个特定类型的视图控制器向特定类型的UIView发送方法,其中UIView本身由许多其他视图组成 视图应该有一个丰富的、特定于域的接口,允许控制器在它和类似丰富的模型之间有一个薄薄的“粘合”层 因此我们覆盖控制器的视图属性如下: @interface PlaybackViewController : UIViewController<StageLayoutDelegate, ControlPanelDelegate> { NSMutableArray* _sectio

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

视图应该有一个丰富的、特定于域的接口,允许控制器在它和类似丰富的模型之间有一个薄薄的“粘合”层

因此我们覆盖控制器的视图属性如下:

@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
@interface PlaybackViewController:UIViewController
{
NSMutableArray*_段;
照明模式_照明模式;
}

@属性(非原子,强)PlaybackView*视图;// 我认为重写UIViewControllers视图属性不是一个好方法

我认为这样做更好:

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

//@property (nonatomic, strong) PlaybackView* view; //you do not need this property

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

@end
您可以像这样使用PlaybackView

((PlaybackView *)(self.view)).oscClient

[更新]
最后,我可能找到了一个适合这个问题的解决方案:
这是一个快速而肮脏的方法,只是为了抑制警告,请尝试在这些行之间包装代码

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu" 
//YOUR CODE
#pragma clang diagnostic pop
或-墙 有关编译器警告抑制的详细信息

[旧答案]
我想给我的2美分。 如果我理解得很好,您正在尝试创建一种抽象工厂,它会根据视图控制器的功能性为您提供一个视图的专用版本。在我看来,故事板在这种设计中不起作用,但我想给大家介绍一下我对它的看法

首先,我将为视图控制器创建一个抽象类,在该类中,您可以在接口中声明所有VC子类中需要的所有属性,例如:

  • OSClient
  • 抽象舞台视图
  • 回放视图较弱
  • playbackProperty
PlaybackView类是一个类集群,如NSNumber,您可以在其上调用一个工厂方法,它将返回一个可能因情况而异的对象。如果检查NSnumber,如果创建浮点或整数,它将返回不同的对象,但它们都是NSnumber的子类,NSnumber声明其子类的所有属性,但不实现它们。
现在,您可以在抽象类的-viewDidLoad方法中调用这样的方法

PlaybackView *plbackView = [PlaybackView playbackViewFroProperty:self.playbackProperty];
[self.view addSubview:playbackView];
self.playbackView = plbackView;

Playback属性可以在viewcontroller情节提要编辑器中的
用户定义的运行时attibute
中进行赋值。

从某种意义上说,您可以声明另一个为您提供强制转换的方法

@implementation PlaybackViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    //  use view_ property instead of view
    self.view_.foo = 1;
}

- (void)loadView {
    CGRect frame = [UIScreen mainScreen].applicationFrame;
    self.view = [[PlaybackView alloc] initWithFrame:frame];
}

- (PlaybackView *)view_ {
    return (PlaybackView *)self.view;
}

这不是最干净的方法,但它确实避免了对
self.view
(通过不使用
self.view
)的强制转换这里的问题不是重写属性,而是使用类类型的前向声明

所以这个

@class PlaybackView;

@interface PlaybackViewController : UIViewController

@property (nonatomic, strong) PlaybackView* view;

@end
将向您发出上述警告,因为编译器无法知道
PlaybackView
的继承层次结构
UIViewController
有一个从其
view
属性提供
UIView
的合同

它告诉你它认为
PlaybackView
不是
UIView

这里的简单解决方案是使用
#导入
,让编译器完全了解
回放视图

#import "PlaybackView.h"

@interface PlaybackViewController : UIViewController

@property (nonatomic, strong) PlaybackView* view;

@end

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

如另一个答案中所建议,使用
#import
而不是
@class
将清除警告,但建议在标题中导入尽可能少的内容,因此我建议保持
视图
不变,并增加一个
PlaybackView*PlaybackView

  • 视图
    回放视图
    都指向同一个视图是非常好的
  • 需要了解专用
    视图
    的类必须导入控制器标题,因此它们可以首先使用
    playbackView
  • 更重要的是,如果您希望在将来将专用视图嵌入为子视图(这通常像添加
    UIScrollView
    superview一样发生),您就不必重构其他代码和类
  • 很干净

@jasperbluse在我看来,它更灵活,比如navigationBar.leftItem,我们不覆盖leftItem,我们只给leftItem一个buttonItem。如果您的视图有时需要是PlaybackView1类型,有时需要是PlaybackView2类型,只需在loadView中添加一个bool即可处理。如果重写,我认为这不容易。为什么不创建一个视图子类,并使用主VC视图作为容器?苹果公司建议,子类LanguableViewController的组合总是能够做到你所说的,结果是不够灵活,几乎毫无用处。我会认真考虑这种方法。它稍后可能会咬你。这是一个快速而肮脏的过程,只是为了抑制警告,尝试在这些行之间包装你的代码
#pragma-clang诊断推送#pragma-clang-diagnostic-ignored“-Wgnu”//your-code#pragma-clang-diagnostic-pop
或-Wall@JasperBlues我已经编辑了我的答案,但是,当然,请先试一下。@KirbyTodd我同意UITableViewController的用途有限,但我不认为是因为它与UITableView紧密耦合。在许多情况下,视图控制器与特定类型的视图交互。这样做有助于控制器发挥其预期的作用,成为丰富视图和模型之间的一层薄薄的粘合层。不,对不起,我一定是把问题说得不好。我所要做的就是在UIViewController子类中将UIView的类型指定为eg PlaybackView*(抽象部分是一个模糊的概念)。如果你这样做,叮当实际上会发出警告,迫使你到处施放。对于简洁的代码,我希望避免使用casti
@class PlaybackView;

@interface PlaybackViewController : UIViewController

@property (nonatomic, strong) PlaybackView* view;

@end
#import "PlaybackView.h"

@interface PlaybackViewController : UIViewController

@property (nonatomic, strong) PlaybackView* view;

@end