Objective Cで私はさまざまなスレッドのNSMutableArrayインスタンスを使用していますが、スレッドセーフであるように@synchronizedを使用しています。現在この配列への私のすべてのアクセスは@synchronizedブロック、さらにはobjectAtIndex:メソッドで保護されています。それにもかかわらず、どのメソッドが本当に@synchronizedで保護される必要があるのでしょうか?読み取りアクセスを保護する必要はありますか?NSMutableArrayコレクションと@Synchronizedブロック
'ObjectAtIndex'が 'removeObject'と同時に保護されていない場合はどうなりますか?
すべてのメソッドが@synchronizedによって保護されている場合、パフォーマンスはどうですか? (私はtcp/udpゲームサーバーを作成し、perfを減らしたり、ロックを生成したりする場合、これらの配列をオーバープロテクトしたくありません。
たとえば、私は 'containsObject:'メソッドがオブジェクトを見つけるために列挙し、別のスレッドで 'removeObject:'へのconcurent呼び出しを避けるべきだと思います。
おそらく、良い解決策があまりにも違うロック持っている(読み取りのためにおよび書き込みアクセス)することです...
ヘルプや提案は大歓迎です!
ありがとうございます。
説明するために以下のサンプルコードを見つけてください:
@interface TestClass : NSObject
{
NSMutableArray * array;
}
@end
@implementation TestClass
- (id)init
{
self = [super init];
if (self)
{
array = [NSMutableArray array];
}
return self;
}
-(id)objectAtIndex:(NSUInteger)index
{
@synchronized(array) **// IS IT USEFUL OR NOT ??**
{
return [array objectAtIndex:index];
}
}
-(void)removeObject:(id)object
{
@synchronized(array)
{
[array removeObject:object];
}
}
-(void)compute
{
@synchronized(array)
{
for (id object in array)
{
[object compute];
}
}
}
@end
私はGCDソリューションが本当に好きです。私が保護したい多くの可変配列(および辞書も)を使用しているので、私は自分自身のGCDMutableArrayとGCDMutableDictionaryを作成して、すべてのメソッドをオーバーライドし、arrayまたはdictionaryの各インスタンスに対してdispatch_queue_tを追加できるのだろうかと思います。しかし、独自のdispatch_queueで10個の可変ディクショナリを持つのは良い解決策ですか?そして、それぞれのインスタンスで異なるキューを作成するには? dispatch_queue_createは、この名前を生成するにはどのようにargとして名前を取るか?おそらく、この種の保護された配列と辞書は既に書かれていますが、何も見つけることはできません。 –
私はそのようなクラスは一般的には有用ではないと思います。コンテナなどの低レベルクラスに集中してスレッドの安全性を実現することはほとんどありません。それらの抽象化のレベルでクラスを解析する必要があるのは、その実装だけでなく、スレッドの安全性のためのインタフェースを設計することです。つまり、ディスパッチキューは安価であり、Appleは合理的な設計が求められるほど多くのものを作成することを奨励しています。 –