セカンダリスレッドでボタンアクションを実行する

私は、私がAPPがクラッシュして、私に以下のエラーメッセージを表示するようにすると、私がセカンダリスレッド(以下のセカンダリスレッドコードを参照)でボタンアクションを実行できない理由を知りたい。

NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(insertdata) object:nil];
[thread start];

void _WebThreadLockFromAnyThread(bool), 0x6a8cfe0: Obtaining the web lock from a thread other than the main thread or the web thread. UIKit should not be called from a secondary thread.

bool _WebTryThreadLock(bool), 0x6a8cfe0: Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now...

1   WebThreadLock
2   -[UIFieldEditor setText:andSetCaretSelectionAfterText:]
3   -[UITextField setText:]
4   -[XYZ reset]
5   -[XYZ insertdata]
6   -[NSThread main]
7   __NSThread__main__
8   _pthread_start
9   thread_start

しかし、スレッドをメインスレッド(メインスレッドコードを参照)に変更すると、クラッシュは見られず、APPは完全に実行されます。誰が違いは何かを説明することができます、なぜ私はアクションのセカンダリスレッドを実行することはできません。

[self performSelectorOnMainThread:@selector(insertdata) withObject:nil waitUntilDone:NO];

ありがとう。

0

1 答え

エラーメッセージには、正確な理由が示されています。

メインスレッド以外のスレッドからウェブロックを取得する   ウェブスレッド。 UIKitはセカンダリスレッドから呼び出されるべきではありません。

操作に時間がかからない場合は、バックグラウンドスレッドで実行する必要はありません。 に時間がかかる場合は、データの取得(または時間がかかるもの)をUI更新から分離し、バックグラウンドでデータ検索を実行してからメインスレッドに戻って更新する必要がありますUI。好ましくはGCDを使用する:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_NORMAL, 0), ^{
    [self downloadData];//takes long
    dispatch_async(dispatch_get_main_queue(), ^{
        [self updateUI];//here you can safely call UIKit
    });
});
1
追加された
あなたはUIKit以外のほとんどのものにバックグラウンドスレッドを使うことができます。 GCDは明示的なスレッド管理よりはるかに優れており、ドキュメントを読んでください。バックグラウンドスレッドからメインスレッドへの切り替えは、上のコードサンプルですでに説明されています。「メインキューでのディスパッチ」のことです。
追加された 著者 zoul,
おそらく [resultsText setText:@ "some data"] のようになります。この部分は、あなたのコードがしなければならないものに完全に依存しています。
追加された 著者 zoul,
ほとんどの場合、多少間違ったことをしていて、間違ったスレッドでコードを呼び出している可能性があります。 + [NSThread isMainThread] を見て、本当にメインスレッドにいるかどうかを確認してください。それでも問題が解決しない場合は、コードサンプルで新しい質問を投稿することをお勧めします。
追加された 著者 zoul,
解説してくれてありがとうございます。そこで、私たちは、ダウンロードやバックグラウンド操作をしているときにのみ、セカンダリスレッドの操作を使用する必要があります。 GCD(Grand Central Dispatch)はセカンダリスレッドとどのように似ていますか?バックグラウンド操作でセカンダリからメインスレッドに切り替える方法
追加された 著者 Santosh Gurram,
UIを更新する方法を知っていてもいいですか?私のUIにresultsTextという名前のtextFieldが含まれている場合、updateUIには何が含まれていますか?
追加された 著者 Raj,
私はresultsText.text = nilで試してみました。それ以降もWebスレッドロックを引き起こしています
追加された 著者 Raj,