如何在 Swift (MVC) 中引用控制器

How to reference controllers in Swift (MVC)

我有一个 window 申请。目前我有一个 xib 文件(MainMenu.xib)和一个 .swift 文件(AppDelegate)。

如果我想向 UI 添加控件并将特定控制器分配给其中一些 UI 组件以在单独的文件中处理其他功能,例如带有 TextViewController 的 NSTextView - 我如何从我的 AppDelegate 中获取对 TextViewController 的引用?

大多数教程在此止步并假设每个人都想使用@IBOutlets 从 AppDelegate 访问控件的属性。

我知道你可以使用 segues (prepareForSegue) - 但我的应用程序没有使用故事板,我想更好地了解 cocoa 中的 MVC 实现。

任何对象都可以有自己的控制器。 AppDelegate 不是圣杯,它只是一个实现 UIApplicationDelegate 协议中方法的对象。它不是您可能希望连接的所有东西的通用配电盘。

一些教程通过将 AppDelegate 用作放置东西的快速而讨厌的地方来开始 Cocoa 开发极大的损害。对于故事板应用程序,所有这些都需要包含在符合 NSApplicationDelegate

的 class 中
import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

}

也就是什么都没有。

名义上的模式是一个屏幕有一个控制器,但当您使用嵌入模式控制一个 window 中的子视图时,即使这样也不是真的。但是请考虑简单的 Cocoa Application 项目模板

ViewController class 是 NSViewController 的子 class,您可以将 IBOutlet 放置在 NSTextView 中以及在该上下文中与它交互的一些逻辑。

import Cocoa

class ViewController: NSViewController,NSTextDelegate {

    @IBOutlet var textView: NSTextView!

    override func viewDidLoad() {
        super.viewDidLoad()

        configureTextController()
    }

    var textController:TextFieldInteractionManager!
    func configureTextController() {
        //textcontroller can be local var , alternatively inject it into this VC
        textController =  TextFieldInteractionManager(textView)
    }


}

如果您想要在整个项目中进行特定的交互,您可能希望将它们放在另一个 class 中,比如 TextFieldInteractionManager 并使其成为文本字段的委托。在构造视图控制器时,您会将文本字段传递给管理器 class。

假设的 TextFieldInteractionManager 可能在本地创建或在 ViewController 实例设置期间注入,即 prepareForSegue(segue: NSStoryboardSegue, sender sender: AnyObject?)。可能性多种多样,取决于您的应用程序的范围以及您希望如何管理您的参考资料。

我常用的模式是有一个 Root 视图控制器,它将引用向下传递到链中的下一个控制器。 YMMV

Dependancy Injection 是一个值得了解的好模式。

Massive View Controller 是一个很好的反模式,需要了解并避免。

这就是我说去获取一些领域知识时的意思。它是一个不断扩展的东西树,需要了解以及为什么你的问题本身不适合 SO。