3

バグがあり、UIの外観が破壊されたり、UI要素の一部が重複したり、サブビューに2回追加されたりしました。バグはほとんど再現されないため、修正するのは困難です。その理由を考えたのですが、おそらくUIを変更するメソッドが同時に2回呼び出されているのでしょう。そして私は正しかった、私はプログラムでバグを作成しようとした。

メソッドが異なるスレッドによって同時にアクセスされることによって引き起こされるバグがあります。この問題をエミュレートし、それをよりよく理解するため。以下に掲載されているコードを参照してください。

これを行うと、updatePresenceメソッドが呼び出され、プログラムは完全に機能します

ViewController.m

-(void)loadConversationScreen{
    [conversationController updatePresence];
}

しかし、これを行うと、プログラムに問題が発生します

ViewController.m

-(void)loadConversationScreen{
    [conversationController performSelectorInBackground:@selector(updatePresence) withObject:nil];
    [conversationController updatePresence];

}

これは、メソッドが同時にアクセスされており、UIViewのインスタンスも同時にアクセス/変更されているためです。

2つのスレッドが同時にメソッドを使用するのを適切に停止するはどうすればよいですか?

IOSでそれを適切に処理するにはどうすればよいですか(適切な方法がない場合、回避策は何ですか)、組み込みのロックまたは何かがありますか?

私のアプリはiOS4.0以降をサポートする必要があります

皆様のご協力に感謝いたします。

4

2 に答える 2

6

あなたに最適なスレッドロックはです@sycnhronized(object) {}。これは、一度に1つのスレッドのみがコードを入力できることを意味します。渡されたオブジェクトは、ロックを実行するために使用されます。一度に特定のオブジェクトの同期によって保護されているブロックに入ることができるのは1つのスレッドだけです。他の人は待ちます。これは、任意のObjective-CオブジェクトにすることができますNSString

通常、複数のスレッドから保護しようとしているオブジェクトを使用します。あなたはおそらく欲しいです@synchronized(self) {}

-(void)updateVariables {
    @synchronized(self) {
        _foo = 1;
        _bar = 2;
    }
}

@sycnhronized同じスレッドが必要なだけ深く呼び出すことができるという意味で、は再入可能@sycnhronizedです。たとえば、次のようになります。

- (void)a {
    @synchronized(self) {
        // entered "immediately" if called from b, where the @synchronized has
        // already been called
        _foo = _foo + 1;
    }
}

- (void)b {
    @synchronized(self) {
        [self a];
    }
}

後世のために、そして説明を読む前にすでに入力したので、UIの更新だけを本当に気にしているのであれば、次のように代わりにメインスレッドに呼び出しを強制することをお勧めします。

- (void)someTask {
    dispatch_async( dispatch_get_main_queue(), ^{
        [self updateUI];
    });
}

- (void)updateUI {
    NSAssert( [NSThread isMainThread], @"called from non-main thread" );
    // do UI updates here
}
于 2012-07-05T06:54:51.637 に答える
2

warrenmが言ったようUIViewに、メインスレッド(UIスレッド)とは別のスレッドから更新するべきではありません。それでも、何が起こっているのかについての回避策があるかどうか尋ねました。正直なところ、メソッドへの2番目のスレッドのアクセスをブロックするのではなく、メソッドが2回呼び出される理由を理解するようにしてください。これは他の何よりも論理的な問題であり、ショートカットを試すのではなく、それを修正する必要があります。

于 2012-07-05T06:54:10.130 に答える