Joseph DeCarloが述べたように、ある場所で配列を作成して別の場所で使用するだけの場合は、にコピーNSMutableArray
する必要はありません。NSArray
たとえば、次のステートメントは有効です。
NSArray* newArray = [NSMutableArray array];
またはコード内:
-(NSArray*)returnAnArray
{
NSMutableArray* editableArray = [NSMutableArray array];
[editableArray addObject:[[NSObject alloc] init]]; //an exemplary object added to the array
return editableArray;
}
ただし、元の配列がインスタンス変数に格納されている場合など、特定のケースでは、NSMutableArray
へのキャストが安全でない場合があります。NSArray
その配列にオブジェクトを追加したり、その配列からオブジェクトを削除したりすると、返された配列が同時に列挙された場合にクラッシュが発生する可能性があります。例えば:
-(void)createArray
{
self->editableArray = [NSMutableArray array]; // instance variable: NSMutableArray* editableArray
}
-(void)addObjectToArray
{
[self->editableArray addObject:[[NSObject alloc] init]];
}
-(NSArray*)getArray
{
return self->editableArray;
}
-(void)enumerateArray
{
for(NSObject obj in [self getArray])
{
// do something with obj
}
}
addObjectToArray
(バックグラウンドスレッドなどから)同時に呼び出された場合enumerateArray
、列挙中に基になる配列が変更されるため、アプリケーションがクラッシュします。として返されるかどうかは関係ありませんNSArray*
。このような場合@synchronized
、複数のスレッドによる同じオブジェクトへのアクセスを同期するために追加するかarrayWithArray:
、提案されているように配列全体をコピーする必要があります。ただし、ドキュメントにはスレッドセーフかどうかが記載されていないため、とにかく呼び出しをarrayWithArray:
追加します。@synchronized
arrayWithArray: