我的程序由三个相对不同的区域组成:在网络上侦听新状态,执行网络操作以及更新UI。所以我分别想要三个类:StateListener,ActionSender和ViewController,每个类都在不同的线程上进行。
它会如此简单 - 三者需要互动。 StateListener发现的一些状态要求ActionSender发送动作,或者由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引用来更新视图后动作,但我尝试在ViewController.init中初始化ActionSender,并且我得到了一些我没有实现的Code.init的奇怪错误......)。我想在 ViewController上面得到并在ViewController初始化的地方初始化所有这些OperationQueues和对象,但是我无法找到它的位置......
我上面所做的基本上是每个对象和OperationQueue的对象引用注入。我知道还有其他方法可以做到这一点(回调的层次结构,NSNotifications),但我不确定哪种方式最好。
我的问题分为两部分:
获得我想要的对象间和线程间通信的最佳方式是什么(即最快,最容易实现和维护,最常用的是Swift)?
我目前从ViewController的viewDidLoad函数开始,看起来很糟糕(这意味着我无法获得ViewController的更高级别的视角。这个东西应该去吗?AppDelegate将自己称为“程序初创公司”区域,但是我无法从那里访问ViewController ...... XCode似乎隐藏了我的应用程序的启动! / p>
我非常感谢您的回复!
答案 0 :(得分:0)
这篇文章极大地帮助了问题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()
}
}