如何跨多个视图控制器引用同一个类的实例?

Posted

技术标签:

【中文标题】如何跨多个视图控制器引用同一个类的实例?【英文标题】:How do I reference to the same instance of a class across multiple viewcontrollers? 【发布时间】:2017-01-29 23:44:22 【问题描述】:

或者换句话说...如何将一个类的一个实例的动作委托给三个不同的视图控制器?在撰写本文时,我将一个类作为公共变量启动,使我的所有视图控制器都可以访问它以将自己设置为委托。但我不喜欢这种方法,因为它把我限制在类的一个实例上。

我的目标是创建一个类的实例,它能够将某些事情委托给三个视图控制器 - 而不会将其公开。我想使用类的原因是因为我希望能够启动 samme 类的更多实例,但如果它是 View Controller 类之外的硬编码公共变量,我不能这样做。

我会尽力解释这个问题。提前致谢!

1) 我有三个视图控制器和一个拆分视图控制器:

截图如下:

2) 我有一个名为“ConnectionHandler”的类。该类的目的是连接到 WebSocket,维护连接并在接收到特定数据包时执行某些操作。 ConnectionHandler 类也继承自另一个类“PacketHandler”。

3) ConnectionHandler 和 PacketHandler 都需要将某些事情委托给三个不同的视图控制器:主视图控制器,另一个包含 NSTextView 的视图控制器,最后一个包含 NSTableView 的视图控制器。

我将提供一些我的代码,我将从我的 ConnectionHandler 开始:

import Starscream

class ConnectionHandler: PacketHandler, WebSocketDelegate 

    let ws = WebSocket(url: URL(string: "ws://localhost:8080")!)

    func connect() 
        ws.delegate = self
        ws.connect()
    

    func disconnect() 
        ws.delegate = nil
        ws.disconnect()
    

    func websocketDidReceiveMessage(socket: WebSocket, text: String) 
    

    func websocketDidConnect(socket: WebSocket) 
    

    func websocketDidDisconnect(socket: WebSocket, error: NSError?) 
    

    func websocketDidReceiveData(socket: WebSocket, data: Data) 
    

还有我的 PacketHandler 中的重要部分:

class PacketHandler 

    var textViewDelegate: TextViewAppendDelegate?

    func message(packet: String) 
        // A message is detected, so I want to push this to a TextView
        textViewDelegate?.appendTextView(str: packet)        

        

协议:

protocol TextViewAppendDelegate 

    func appendTextView(str: String)


还有 View Controller,ConnectionHandler/PacketHandler 将操作委托给:

class TextViewController: NSViewController, TextViewAppendDelegate 

    @IBOutlet var textView: NSTextView!

    func appendTextView(str: String) 
        // Code to append a message to a NSTextView
    

    override func viewDidLoad() 
        super.viewDidLoad()
        socket.textView = self 
    

正如我所说,我只是将 ConnctionHandler 类作为公共变量启动,因为这是我知道如何委托给多个视图控制器的唯一方法。 如果我在主视图控制器中启动类,我发现自己无法委托给其他视图控制器。

我曾考虑将所有三个视图控制器链接到同一个视图控制器类,但我也不确定那个。我还考虑过从三个 View Controller 之一启动 ConnectionHandler,然后(以某种方式)在 View Controller 之间创建委托,使其他 View Controller 可以将自己设置为类的某些方面的委托。 我想我的想法是“视图控制器”需要了解(或访问)“类”的一个实例,才能将其“设置为自己”作为委托。还有其他更好的方法吗?

再次,非常感谢。

更新: 如果想使用单例,雅各布斯的回答可以工作。所以我给了他正确的答案。但经过更多挖掘后,我了解了 NotficationCenter,它适合我的需求!

【问题讨论】:

【参考方案1】:

你正在寻找的是一个单例类。

Apple Docs 将其定义为:

无论应用程序请求多少次,单例类都会返回相同的实例。

你可以这样实现:

 class ConnectionHandler 
     static let sharedInstance = ConnectionHandler()
     ...the rest of your code

然后在您的所有视图控制器中访问 sharedInstance。

【讨论】:

嗨雅各布,感谢您的快速响应!所以,如果我要像这样在我的主视图控制器中启动类:var socket = ConnectionHandler() 我只需要在其他控制器中引用它,就像这样:var socket = ConnectionHandler.sharedInstance 它会是同一个实例吗?太好了,伙计!非常感谢。 您甚至不必这样做。只需在需要的任何地方说 ConnectionHandler.sharedInstance。 但是我想知道...假设我想创建一个选项卡式应用程序,其中每个选项卡都有它自己的这三个视图控制器的实例。每个选项卡也会访问同一个共享实例吗? 是的。查看文档中的 AVAudiosession。它的工作原理相同。

以上是关于如何跨多个视图控制器引用同一个类的实例?的主要内容,如果未能解决你的问题,请参考以下文章

一个窗口中跨多个视图控制器的 Cocoa 绑定

iPhone xcode - 从多个视图控制器控制音频的最佳方式

如何将依赖项注入 iOS 视图控制器?

如何在同一类的 awakeFromNib 方法中获取当前视图控制器?

在 Swift 中跨多个选项卡访问相同的视图模型

Facebook iOs sdk iphone:从多个视图控制器调用