Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.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 正在确定控制器的范围';自定义视图下的s代码是一个好的cocoa设计模式吗?_Ios_Cocoa_Model View Controller - Fatal编程技术网

Ios 正在确定控制器的范围';自定义视图下的s代码是一个好的cocoa设计模式吗?

Ios 正在确定控制器的范围';自定义视图下的s代码是一个好的cocoa设计模式吗?,ios,cocoa,model-view-controller,Ios,Cocoa,Model View Controller,当我在思考MVC在Cocoa中的所有体现时,我想我可以为应用程序中的每个视图创建一个自定义类,并用数据源和主要考虑用于控制器的委托内容填充它 这样,我就不需要臭名昭著的大型视图控制器,而是可以切掉一些代码片段,将它们放在单独的文件中——一个类对应一个视图——以及它们的数据源和委托 这是一个好主意,还是它的缺点是什么?我担心你的想法听起来会导致一堆臃肿的视图,而不是一堆臃肿的控制器 我建议考虑一下:一个实体应该有一个目的或功能。视图的功能是什么 它是屏幕某个区域的代码表示。这意味着它需要做两件事:

当我在思考MVC在Cocoa中的所有体现时,我想我可以为应用程序中的每个视图创建一个自定义类,并用数据源和主要考虑用于控制器的委托内容填充它

这样,我就不需要臭名昭著的大型视图控制器,而是可以切掉一些代码片段,将它们放在单独的文件中——一个类对应一个视图——以及它们的数据源和委托


这是一个好主意,还是它的缺点是什么?

我担心你的想法听起来会导致一堆臃肿的视图,而不是一堆臃肿的控制器

我建议考虑一下:一个实体应该有一个目的或功能。视图的功能是什么

它是屏幕某个区域的代码表示。这意味着它需要做两件事:绘制到它的区域并注册与该区域的交互。对于这两个子任务来说不是绝对必要的任何内容都不应该出现在view类中

这就是“愚蠢的观点”的观点。它没有逻辑,没有决策。它只是得到一些要渲染的数据。当它被点击时,它不知道输入代表什么,也不知道该怎么做。它只知道交互的类型并告诉另一个对象

另一个对象是视图的控制器。视图控制器的职责是在视图和系统其余部分之间进行调解。它为视图提供了数据。它还接受来自视图的关于输入的消息,然后根据这些消息的结果重新配置视图

但是,视图控制器不一定需要自己计算结果。这通常是视图控制器开始陷入“大规模”麻烦的地方。视图控制器应拾取另一个对象,以帮助其获取交互生成的新值

另一个对象的一种可能性是视图模型,位于中。视图模型是视图原始数据的以显示为中心的表示形式。它将模型中的信息转换为视图所需的任何格式,并根据视图控制器的输入重新转换或更新数据

另一个想法是,通过安排,更精细地分担责任。在这里,数据的格式由“演示者”处理,数据的转换是“交互者”的工作

这里有可能进入建筑宇航员的领地;如果视图的需求本质上非常简单,盲目地应用复杂的结构可能会对您不利。但是,即使您选择不正式应用这些可选模式之一,视图控制器也需要其他对象。您将需要具有其他特定作业的“控制器”,这些作业从视图控制器获取消息并传回数据


重要的是要记住我提到的原始想法:努力让每种类型的都做一件事,并且把它做好。这将使你的课程专注;易于阅读、理解和思考;可测试。

视图不计算数据,只显示数据。然而,若您有自定义控件,它可以有一些逻辑来计算它的内部数据,以触发模型内的值更改

你的方法是一种过度使用不必要代码的方法

因此,您面临一个需要设置自定义NSView或自定义NSControl(例如NSButton标题)的一些值的问题

一些可用的MVC解决方案:

  • 手动设置控制器内的值,并在已更改属性的视图内调用setNeedsDisplay方法
  • 将模型对象设置为视图的属性。但是,这引入了紧密耦合,但仍然可以(因此视图必须 了解/导入模型类)+在视图中包含更新/刷新方法
  • 使用到nsobjectcontroller的绑定。您不需要设置nsobjectcontroller的类(仅当您需要额外的 类似于在添加时自动创建对象的功能 方法)
  • MVC模式提醒 视图具有在控制器中触发的目标操作机制。控制器更新模型(无其他!)。然后,模型必须传播它已经改变的信息,控制器应该对此做出反应。它不应该在目标动作中做出反应

    使用绑定可以跳过目标操作,但目标操作仍然存在

    你可以把2和3结合起来

    如果您是初学者,请忘记毒蛇模式。MVVM可以帮助您减小控制器的大小

    如何与NSObjectController一起使用绑定:

    #导入
    #导入“AppDelegate.h”
    #导入“Value.h”
    @接口AppDelegate()
    @属性(弱)窗口*窗口;
    @属性(弱)IBMObjectController*objectController;
    @属性(强)值*值;
    @结束
    @实现AppDelegate
    -(无效)ApplicationIDFinishLaunching:(NSNotification*)通知{
    self.value=[[value alloc]init];
    self.objectController.content=[self value];
    }
    @结束
    @接口值:NSObject
    @属性NSString*value1;
    @属性NSString*value2;
    @属性字符串*值3;
    @结束
    #导入“Value.h”
    @实施价值
    -(instancetype)初始化
    {
    self=[super init];
    如果(自我){
    [自我设置值1:@“值1”];
    [自我设置值2:@“值2”];
    [自我设置值3:@“值3”];
    }
    回归自我;
    }
    @结束
    
    还有一个选项可供选择。简而言之:应用程序中的每个任务都由一个协调器对象管理,该对象管理其视图控制器


    还有一个主协调器对象,由应用程序委托保留,并保留所有其他控制器。所有不属于视图控制器的逻辑都上移到协调器。

    我建议使用MVVM模式,其中视图控制器更像视图,视图模型正在完成大部分工作。然后,可以通过注入不同的视图模型重用视图控制器
    #import <Foundation/Foundation.h>
    
    #import "AppDelegate.h"
    #import "Value.h"
    @interface AppDelegate ()
    
    @property (weak) IBOutlet NSWindow *window;
    @property (weak) IBOutlet NSObjectController *objectController;
    @property (strong) Value *value;
    @end
    
    @implementation AppDelegate
    
    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
        self.value = [[Value alloc] init];
        self.objectController.content = [self value];
    }
    
    @end
    
    @interface Value : NSObject
    
    @property NSString *value1;
    @property NSString *value2;
    @property NSString *value3;
    
    @end
    
    #import "Value.h"
    
    @implementation Value
    
    - (instancetype)init
    {
        self = [super init];
        if (self) {
            [self setValue1:@"Value1"];
            [self setValue2:@"Value2"];
            [self setValue3:@"Value3"];
        }
        return self;
    }
    
    @end