2017-01-29 8 views
1

Или другими словами ... Как мне делегировать действия из одного экземпляра класса, трех разных контроллеров просмотра? В это время написания я запускаю класс как общедоступную переменную, позволяя всем своим диспетчерам view получать доступ к нему, чтобы установить себя как делегат. Но мне не нравится этот подход, потому что он ограничивает меня одним экземпляром класса.Как я могу ссылаться на один и тот же экземпляр класса через несколько контроллеров просмотра?

Моя цель - создать экземпляр класса, который может делегировать определенные вещи трем диспетчерам просмотра, не делая его общедоступным. Причина, по которой я хочу использовать классы, заключается в том, что я хотел бы иметь возможность запускать больше экземпляров класса samme, но я не могу этого сделать, если это жесткая переменная public вне класса View Controller.

Я попытаюсь объяснить эту проблему, а также могу. И спасибо заранее!

1) У меня есть три View Controllers, и один Split View Controller:

Вот скриншот:

storyboard

2) У меня есть класс с именем "ConnectionHandler". Цель этого класса - подключиться к WebSocket, поддерживать соединение и делать определенные вещи при получении определенных пакетов. Класс ConnectionHandler также наследуется от другого класса «PacketHandler».

3) Как ConnectionHandler, так и PacketHandler должны делегировать определенные вещи трем различным контроллерам View: контроллеру основного представления, другому контроллеру представления, который содержит NSTextView, и, наконец, View Viewer, который содержит 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, который 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. Если я инициирую класс в главном контроллере просмотра, я не могу делегировать его другим Контроллерам.

Я подумал о том, чтобы связать все три контроллера View с тем же классом контроллера View, но я не уверен в этом. Я также подумал о том, чтобы инициировать ConnectionHandler из одного из трех контроллеров View, а затем (каким-то образом) создавать делегаты между контроллерами View, позволяя другим контроллерам View, чтобы он определил себя как делегат определенных аспектов класса. Я предполагаю, что мой менталитет состоит в том, что «View Controllers» должен знать о (или доступ) экземпляр «класса», чтобы иметь возможность «установить его самостоятельно» в качестве делегата. Есть ли другой, лучший способ?

И еще раз большое спасибо.

Обновление: Ответ Jacobs может работать, если вы хотите использовать Singleton. Поэтому я дал ему правильный ответ. Но после некоторого дополнительного рытья я узнал об NotficationCenter, который соответствовал моим потребностям!

ответ

1

Что вы ищете - это одноэлементный класс.

В Apple Docs определить это как:

одноплодной класс возвращает тот же экземпляр, независимо от того, сколько раз просит его приложение.

Вы бы осуществить это как:

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

Тогда во всех ваших View контроллера вы получаете доступ к sharedInstance.

+0

Привет, Якоб, спасибо за быстрый ответ! Итак, если бы я должен был инициировать класс в моем главном контроллере представления, например: 'var socket = ConnectionHandler()' Мне просто нужно ссылаться на него в других контроллерах, таких как: 'var socket = ConnectionHandler.sharedInstance ' И это будет тот же самый пример? Это здорово, мужик! Огромное спасибо. –

+0

Вам даже не пришлось бы это делать. Просто скажите ConnectionHandler.sharedInstance везде, где вам это нужно. – Jacob

+0

Но мне интересно ... Предположим, я хотел бы создать приложение с вкладками, где каждая вкладка имеет собственный экземпляр этих трех контроллеров View. Будет ли каждая вкладка иметь доступ к одному и тому же совместно используемому экземпляру? –