UIKitはスレッドセーフじゃない

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…

いろいろやってたら上記の様なエラーが出て、またハマりました。ググってみるとUIKitがスレッドセーフじゃない為に起きているようです。

何をやってこんなエラーが起きたのかというと、サーバとソケット接続して、サーバからの通信を監視し、送られてきた内容に応じてメインスレッド以外からUIの更新をしようとしました。基本的には動いていたんですが、更新対象のViewControllerにTextViewを含めたら動かなくなりました。

JavaのSwingとかもシングルスレッドだし、UIkitもおそらくスレッドセーフじゃないのだろうなとは思っていましたが、これほど意味不明なエラーが出るとは思いませんでした。

これに対しては

1
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait

というメソッドがNSObjectに用意してあり、指定したメソッドをメインスレッド上で実行する、という機能を持っています。

今回の場合、通信を受け取ったスレッドからdelegateをとおしてViewControllerに通知していたのですが、この通知メソッドにはUI更新の処理は書かずに、別のメソッドにその内容を記述。上記のメソッドから呼び出すことにして安全にUIを書き換える事にしました。

1
2
3
4
5
//ViewControllerに通知するスレッド
switch (header) {
    case PK_USER_AUTH:
        [delegate connection:self didFnishAuth:YES];
        break;
1
2
3
4
5
6
7
8
9
10
11
12
/**
 * 通知を受け取るViewController
 */
//このメソッドが通知を受け取るが処理は別メソッドに投げる
- (void)connection Connection*)con didFnishAuth BOOL)result {
    [self performSelectorOnMainThread:@selector(didFinishAuthExe) withObject:nil waitUntilDone:TRUE];
}
 
//メインスレッド上でこのメソッドが実行され、UIが書き変わる
- (void) didFinishAuthExe {
    [self dismissModalViewControllerAnimated:YES];
}

意味不明なエラー出るとホントてんぱる。


コメントを残す

メールアドレスが公開されることはありません。


*

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>