2016-09-16 13 views
0

私のプログラムは、比較的新しい3つの領域で構成されています。新しい領域のリスニング、ネットワークアクションの実行、UIの更新です。だからそれぞれ私は3つのクラスが必要:StateListener、ActionSender、およびViewController、別々のスレッドに沿ってそれぞれchugging。Swift 3でのスレッド間オブジェクト間通信ココア

それはとてもシンプルだったでしょうか?3人は相互作用する必要がありますか? StateListenerによって検出された一部の状態では、ActionContenderまたはViewControllerによって更新されるUIによってActionが送信される必要があります。アクションに対するいくつかの応答では、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)があることを知っていますが、私はどちらが最善であるか不明です。

私の質問は2つの部分である:オブジェクト間とスレッド間通信を取得する(すなわち、最速、最も簡単にはスウィフトに実装し、維持し、最も慣用に)最良の方法は何

  1. 欲しい?

  2. 私は現在、ViewControllerのviewDidLoad関数からのものを取得していますが、これはひどいと思われます(ViewControllerの高次の視点を得ることができないことを意味します)。AppDelegateは、スタートアップ」面積が、私はそこからのViewControllerにアクセスすることはできません... XCodeのは私から私のアプリの起動を隠されているようだ!

私は本当にあなたの回答に感謝!

+0

これはあまりにも漠然としすぎて、具体的な提案をするのに十分な情報ではなく、何かを達成するための「最良の方法」に関する意見を求めるようです。それは言われている、あなたは決してこのようにいくつかの "状態"の変化を待ってスピンしたくない。あなたはイベントに応答し、プロセス内のスレッドをブロックしないことを望みます。 – Rob

+0

これは、アプリケーションのデリゲートです(アプリのデリゲートではなく、ビューコントローラーへの参照を取得するのではなく、一般的には反対です)。'let appDelegate = NSApplication.shared()。デリゲートを! AppDelegate'または 'let appDelegate = UIApplication.shared.delegateを! AppDelegate')、それによって、アプリケーションデリゲートが管理しているオブジェクトへの参照を取得することができます。 – Rob

+0

ロブ:ご意見ありがとうございます。私は水を濁らせることなくできる限り具体的にしようとしましたが、明らかに十分な詳細を与えることはできませんでした。ごめんなさい!何らかの状態が変わるのを待っていることに対する嫌悪感については、何が違うのですか?あなたがイベントに応答する場合は、必ずイベントを聞く必要がありますか? waitForNewState()は、サーバーが新しい状態をプッシュした場合にのみ返されることを明確にする必要があります。そして状態は厚くて速くなるので、時間の良い部分がそれらを扱うでしょう。 – SuddenMoustache

答えて

0

この投稿は大幅に質問2と初期値のデータメンバへのパラメータとしての自己渡しの問題を助けました: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() 
    } 
} 
関連する問題