2

私はインタビューでこの質問をしました。バックグラウンドスレッドにUILabelを渡すと、どうなるのか知りたいです。GCDまたはNSOperationQueueのバックグラウンドスレッドにUIlabelを渡すとどうなりますか

+0

私はUI要素がメインスレッド上でのみ変更されるべきだと考えています。 http://stackoverflow.com/a/7905497/4475605 – Adrian

+0

これは 'UILabel'で何をしようとしているかによって異なります。 – rmaddy

答えて

2

短い答えは「結果が未定義」または「悪いもの」です。 UIKitはスレッドセーフではないので、わかりませんが、うまくいかないでしょう。

私は、UIの変更がLOOOOOONNNGの時間を有効にするのを見たことがあります。

良い答えは「しないでください」です。

+0

ios 9では、別のスレッドでUI要素を変更すると例外が発生します – Paulw11

+0

@ Paulw11、本当ですか?保証?例外をスローするメカニズムは何ですか? –

+0

「あなたはバックグラウンドスレッドでUIを変更しています」というような例外メッセージが表示される – Paulw11

2

ラベルがビュー階層内にあるかどうかによって異なります。一般的なルールは、バックグラウンドスレッドによって実行されるコードは、view.addSubviewlabel.setNeedsLayoutなどのようなUI更新を引き起こしてはならないということです。そのスレッドでラベルを使って遊んでも安全です。

バックグラウンドスレッドでlabel.textを更新しても、ラベルがビューに追加されると、スーパービューのレイアウトが無効になり、UIがそのスレッド内で更新されるため、危険です。

のは、カスタムUILabelクラスは、UIとは何の関係もありませんコンストラクタの動作を消費するいくつかの時間をやっているとしましょう:

class MyFatLabel: UILabel { 
    override init(frame: CGRect) { 
    super.init(frame: frame) 
    self.text = "Lorem ipsum"   
    self.readDataFromDisk() // will block the main thread. 
    } 
} 

その後、あなたは別のスレッドでそのラベルを初期化にそれを追加することができますUIを持つユーザーとの対話がブロックされ得ることはありませんので、メイン(UI)スレッドビュー:

dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)) { 
    let label = MyFatLabel(frame: CGRectZero) 

    dispatch_async(dispatch_get_main_queue()) { 
    view.addSubview(label) 
    } 
} 

かいつまんで、あなたは、しかし、バックグラウンドスレッドであなたを新しいUILabel(または任意のUIResponder)を初期化することができますUIのupdaをトリガするプロパティのいずれかを変更する必要がありますメインスレッド内のスレッド。

関連する問題