我的程序由三个相对不同的区域组成:在网络上监听新状态、执行网络操作以及更新 UI。因此,我分别需要三个类:StateListener、ActionSender 和 ViewController,每个类都在单独的线程上运行。
事情有这么简单就好了——三者需要互动。 StateListener 发现的某些状态需要 ActionSender 发送 Actions 或 ViewController 更新 UI。某些对 Actions 的响应需要 ViewController 更新 UI。某些 UI 操作需要由 ActionSender 执行操作。
目前我做了这样的事情(伪代码):
/* ViewController.swift */
class ViewController : blah
{
//...
func buttonPressed()
{
// ?! Need to do an action here but I can't
// because actionSender is initialised below...
}
func viewDidLoad()
{
let actionSender = ActionSender(m_view: self)
let actionQueue = OperationQueue()
let stateListener = StateListener(m_view: self,
m_actionSender: actionSender,
m_actionQueue: actionQueue)
let stateQueue = OperationQueue()
stateQueue.addOperation(stateQueue.listen())
}
}
/* StateListener.swift */
class StateListener
{
// ...
func listen()
{
while true
{
var state = waitForNewState()
if shouldActOn(state)
{
m_actionQueue.addOperation(m_actionSender.act())
}
}
}
}
/* ActionSender.swift */
class ActionSender
{
// ...
func act()
{
var reply = sendAction()
OperationQueue.main.addOperation(m_view.m_textBox.append(reply))
}
}
这相本地狱般,甚至没有做我想要它做的事情,因为我无法让 ViewController 执行操作(ActionSender 需要 ViewController 引用来在操作后更新 View ,但我尝试初始化 ActionSender在 ViewController.init 中,我遇到了与我没有实现的 Code.init 有关的奇怪错误...)。我想要到达 ViewController 上方并在 ViewController 初始化的任何地方初始化所有这些操作队列和对象,但我找不到它在哪里......
我上面所做的基本上是每个对象和OperationQueue的对象引用注入(inject)。我知道还有其他方法可以做到这一点(回调层次结构、NSNotifications),但我不确定哪种方法最好。
我的问题分为两部分:
获得我想要的对象间和线程间通信的最佳(即最快、最容易实现和维护、Swift 中最惯用的)方法是什么?
我目前从 ViewController 的 viewDidLoad 函数中获取信息,这看起来很糟糕(并且意味着我无法获得 ViewController 的“更高层”视角。这些东西应该去哪里?AppDelegate 将自己宣传为“程序启动区域,但我无法从那里访问 ViewController...XCode 似乎对我隐藏了我的应用程序的启动!
非常感谢您的回复!
最佳答案
这篇文章极大地帮助了问题 2 以及将 self 作为参数传递给初始化程序中的数据成员的问题:http://blog.scottlogic.com/2014/11/20/swift-initialisation.html
具体来说,我可以使用这种模式:
class Foo : blah
{
var m_bar : Bar!
init() {
// notice I get away with not initialising m_bar
}
func viewDidLoad {
m_bar = Bar(m_foo: self)
m_bar.doYourThing()
}
}
该博客更喜欢以下内容,出于对作者的感谢,我觉得我应该在此处添加这些内容,尽管我更喜欢上面的内容。
class Foo : blah
{
lazy var m_bar : Bar = {
return Bar(m_foo: self) // notice I can pass in self
}
init() {
// notice I get away with not initialising m_bar
}
func viewDidLoad {
m_bar.doYourThing()
}
}
关于swift - Swift 3 中与 Cocoa 的线程间对象通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39537949/