使用Cocoa

时间:2016-09-16 18:27:13

标签: swift cocoa concurrency viewcontroller swift3

我的程序由三个相对不同的区域组成:在网络上侦听新状态,执行网络操作以及更新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),但我不确定哪种方式最好。

我的问题分为两部分:

  1. 获得我想要的对象间和线程间通信的最佳方式是什么(即最快,最容易实现和维护,最常用的是Swift)?

  2. 我目前从ViewController的viewDidLoad函数开始,看起来很糟糕(这意味着我无法获得ViewController的更高级别的视角。这个东西应该去吗?AppDelegate将自己称为“程序初创公司”区域,但是我无法从那里访问ViewController ...... XCode似乎隐藏了我的应用程序的启动! / p>

  3. 我非常感谢您的回复!

1 个答案:

答案 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()
    }
}