0

さまざまなスレッドから実行されるこのコードがあります。デッドロックがどこにあるのかわかりません。たぶん私は@syncronizedがどのように機能するかを理解していません

@synchronized(self) {
    NSLog(@"%@", self);
    NSLog(@"(%d) Aloha hermano blocked?" ,pthread_mach_thread_np(pthread_self()) );
    genres = [aContext executeFetchRequest:request error:&error];
    if (error != nil) {
        NSLog(@"Obj list fetch error: %@", error);
        exit(-1);
    }
    NSLog(@"(%d) Aloha hermano NO" ,pthread_mach_thread_np(pthread_self()) );
}

アプリがロックされたときのトレースは次のとおりです。

2012-11-27 13:28:05.141 (15143) Aloha hermano blocked?
2012-11-27 13:28:05.146 (15143) Aloha hermano NO
2012-11-27 13:28:05.152 <STBConnection_0_9: 0xc676000>
2012-11-27 13:28:05.155 (15143) Aloha hermano blocked?
2012-11-27 13:28:05.161 (15143) Aloha hermano NO
2012-11-27 13:28:05.168 <STBConnection_0_9: 0xc676000>
2012-11-27 13:28:05.171 (15143) Aloha hermano blocked?
2012-11-27 13:28:05.178 (15143) Aloha hermano NO
2012-11-27 13:28:05.185 <STBConnection_0_9: 0xc676000>
2012-11-27 13:28:05.191 (1799) Aloha hermano blocked?

ご覧のとおり、Imは常に同じオブジェクトで同期しています。

何か案は?どうもありがとう

4

1 に答える 1

1

修正しました。問題は、異なるスレッドから同じManagebObjectContextを使用していたことです。その場合、Appleドキュメントは次のように述べています。

管理対象オブジェクトコンテキストまたは永続ストアコーディネーターをスレッド間で共有する場合は、メソッドの呼び出しがスレッドセーフスコープから行われるようにする必要があります。ロックについては、独自のミューテックスを実装する代わりに、管理対象オブジェクトコンテキストと永続ストアコーディネーターでNSLockingメソッドを使用する必要があります。これらのメソッドは、アプリケーションの意図に関するコンテキスト情報をフレームワークに提供するのに役立ちます。つまり、ミューテックスを提供することに加えて、操作のクラスターのスコープを設定するのに役立ちます。

したがって、修正されたコードは次のようになります。

[aContext lock];
genres = [aContext executeFetchRequest:request error:&error];
if (error != nil) {
   NSLog(@"Obj list fetch error: %@", error);
   exit(-1);
}
[aContext unlock];
于 2012-11-27T14:16:19.197 に答える