2017-12-24 7 views
1

上の非同期タスクの実行順序、彼らは(1、2、3、など)が含まれて番号順に実行print文以下のコードでメインキュー

override func viewDidLoad() { 
    super.viewDidLoad() 

    DispatchQueue.main.async { 
     print("4") 
    } 

    print("1") 
} 

override func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(animated) 

    DispatchQueue.main.async { 
     print("5") 
    } 

    print("2") 
} 

override func viewDidAppear(_ animated: Bool) { 
    super.viewDidAppear(animated) 

    DispatchQueue.main.async { 
     print("6") 
    } 

    print("3") 
} 

あなたはなぜ、実行説明することができますプロセスはこのように行われますか? viewDidLoadにブロックを非同期にディスパッチすると、viewWillAppearviewWillAppearメソッドはすでにキューに入っていますか?私たちは非同期viewDidLoadでブロックを派遣する際

+3

私は本当に他に何が期待できるか分かりません...あなたは精巧にできますか? –

+0

なぜそれではないですか:1,4,2,5,3,6?私はなぜディスパッチブロックはVCライフサイクルの対応するメソッドの直後に実行されないのですか? – Legonaftik

+0

非同期呼び出しを行っている場合、なぜそれらが連続していると思われますか? – Alexander

答えて

7

はキューにすでにviewWillAppearviewDidAppear方法はありますか?

実際には:はい。それらは「キュー内」ではありませんが、既存のメインキューコードシーケンスの一部としてすでに列車に乗っています。

ランロップが終わるのは、すべての問題です。メインキューに非同期にディスパッチされたコードは、それが発生するまで実行できません。事実、print 4などが起こる前に、このCATransaction(runloopの1つの "革命")の終わりまで完全に来なければなりません。

おそらく、このログをルートビューコントローラに入力している可能性があります。あなたのアプリが起動しており、makeKeyAndVisibleへの呼び出しがウィンドウに送られるまで何も起こらないので、特別なケースです。

makeKeyAndVisibleの呼び出しの1つとして、この時点でviewDidLoadが呼び出され、viewWillAppearが連続して呼び出されます。

enter image description here

enter image description here

したがって、同じコードが依然としてメインスレッド上で実行されています。あなたの派遣されたコードが実行される瞬間はありませんでした。したがって、何よりも先にprint 1print 2が得られます。 viewDidAppear

状況は少し異なります。

enter image description here

あなたが見ることができるように、我々はmakeKeyAndVisibleへの呼び出しではなくなりました。しかし、メインスレッドはまだ実行中です。トランザクション完了ブロック(cleanUpAfterCAFlushAndRunDeferredBlocks)にすぐに切り替えるからです。 viewDidAppearviewWillAppearのアニメーションの補完ブロックとして効果的に考えることが役立ちます。これはすでにviewWillAppearへの呼び出しの一部として構成されているため、依然として同じトランザクションの一部です。したがって、viewDidAppearはまだviewWillAppearの直後にあり、一時停止することなくprint 3となります。

は、長い起動シーケンスが終了すると、あなたのメインキューの非同期コードは、それがエンキューされた順番(print 4print 5print 6)でない実行する機会を持って最後。