【问题标题】:Accessing controller from model从模型访问控制器
【发布时间】:2011-08-17 13:41:12
【问题描述】:

我有以下类设计:

  • 一个控制器类和一个模型类都继承自NSobject;

  • 具有来自控制器的 IBoutlets 的 UI;

  • 一个模型类,它扫描一组文件的属性并写入文件(使用循环);

  • UI 必须显示当前正在扫描的文件的名称。

如何让模型类与控制器通信?

我在控制器内部创建了一个模型对象,因此为了避免循环,我无法在模型类中创建控制器实例。关于如何实现这一点的任何建议?

【问题讨论】:

    标签: objective-c cocoa model-view-controller delegates


    【解决方案1】:

    在模型的 .h 中定义一个协议,如下所示:

    @protocol FileScannerDelegate
    @required
        - (void)fileScanner:(FileScannerClass *)fileScanner willScanFile:(NSString *);
    @end
    

    添加一个新属性assign 来保存对委托的引用。这需要分配以避免循环引用

    @property (nonatomic, assign) id<FileScannerDelegate> delegate;
    

    在模型 .m 中,您正在扫描您调用的下一个文件

    [delegate fileScanner:self willScanFile:fileName];
    

    在控制器的.h中你需要说你遵循协议

    @interface MyController : UIViewController <FileScannerDelegate> 
    

    在控制器 .m 中。当您在控制器中实例化文件扫描器时,您需要将控制器设置为委托

    fileScanner = [[FileScannerClass alloc] init];
    fileScanner.delegate = self;
    

    然后实现你说的方法

    - (void)fileScanner:(FileScannerClass *)fileScanner willScanFile:(NSString *)
    {
       ...
       // update the UI
    } 
    

    【讨论】:

      【解决方案2】:

      为模型提供对控制器的引用。

      @class MyController
      
      @interface MyModel:NSObject
      
      @property (readwrite,assign) MyController *controller;
      
      @end
      

      并实施

      #include "MyController.h"    
      
      @implementation MyModel
      
      @synthesize controller;
      
      -(void)somethingHappenedToMe
       {
            [controller updateYourself:self];
       }
      
      
      @end
      

      您可以使用委托和私有方法将自己抽象化,但归根结底,您仍然希望模型实例与控制器实例通信。

      【讨论】:

      • 实现协议不需要更多的输入,它通过提供两个对象对话的契约为您提供了一个更强大的最终解决方案。将谨慎抛诸脑后可能在 99% 的情况下都有效,但它不会扩大规模,而 1% 的人会回来用困难的 bug 咬你。
      猜你喜欢
      • 1970-01-01
      • 2018-11-15
      • 2012-08-23
      • 2011-10-22
      • 2013-07-05
      • 2017-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多