NSMutableArrayをNSArrayに変換する方法 客観的c?
NSArray *array = mutableArray;
NSMutableArrayをNSArrayに変換する方法 客観的c?
NSArray *array = mutableArray;
回答:
NSArray *array = [mutableArray copy];
Copy
不変のコピーを作成します。Appleはさまざまな最適化を行うことができるため、これは非常に便利です。たとえばcopy
、不変の配列に送信すると、オブジェクトのみが保持され、が返されますself
。
ガベージコレクションまたはARCを使用しない場合-copy
は、オブジェクトが保持されることを覚えておいてください。
copy
、NSMutableArrayではなく通常のNSArray を作成するドキュメントからどのように見分けることができますか?
NSArray
&NSMutableArray
、NSString
&NSMutableString
。しかし、たとえばNSViewController
常に変更可能な状態が含まれているわけではありません。
NSMutableArray
サブクラスであるNSArray
あなたは、常に変換が、する必要はありませんので、あなたは、アレイは、作成することができます修正することはできませんことを確認する場合はNSArray
どちらかあなたはそれが自動解放かしたいかに応じてこれらの方法を:
/* Not autoreleased */
NSArray *array = [[NSArray alloc] initWithArray:mutableArray];
/* Autoreleased array */
NSArray *array = [NSArray arrayWithArray:mutableArray];
編集: GeorgSchöllyが提供するソリューションは、特にARCがあり、autoreleaseを呼び出す必要がないため、それを行うためのより良い方法であり、非常にクリーンです。
私は2つの主なソリューションの両方が好きです:
NSArray *array = [NSArray arrayWithArray:mutableArray];
または
NSArray *array = [mutableArray copy];
主な違いは、私はそれらに見るにはmutableArrayがnilであるとき、彼らはどのように動作するかです:
NSMutableArray *mutableArray = nil;
NSArray *array = [NSArray arrayWithArray:mutableArray];
// array == @[] (empty array)
NSMutableArray *mutableArray = nil;
NSArray *array = [mutableArray copy];
// array == nil
[mutableArray copy]
に簡略化できます[nil copy]
。Objective-Cでは、 nilに送信されるメッセージは常にnilになります。「何もない」と「何も入っていない配列」の違いを覚えておくことは重要です。
このコードを試してみてください---
NSMutableArray *myMutableArray = [myArray mutableCopy];
そして
NSArray *myArray = [myMutableArray copy];
以下は、NSMutableArrayをNSArrayに変換する方法です。
//oldArray is having NSMutableArray data-type.
//Using Init with Array method.
NSArray *newArray1 = [[NSArray alloc]initWithArray:oldArray];
//Make copy of array
NSArray *newArray2 = [oldArray copy];
//Make mutablecopy of array
NSArray *newArray3 = [oldArray mutableCopy];
//Directly stored NSMutableArray to NSArray.
NSArray *newArray4 = oldArray;
Swift 3.0では、新しいデータ型Arrayがあります。let
キーワードを使用して配列を宣言すると、NSArrayになり、var
キーワードを使用して宣言すると、NSMutableArrayになります。
サンプルコード:
let newArray = oldArray as Array
NSArray *array = mutableArray;
この[mutableArray copy]
アンチパターンはサンプルコード全体に渡っています。一時的で、現在のスコープの最後で割り当て解除される使い捨ての可変配列の場合は、これを停止します。
ランタイムが、範囲外になり、0にデリファレンスされ、永久に割り当て解除されようとしている可変配列の無駄なコピーを最適化できる方法はありません。
NSMutableArray
てもNSArray
変換されません(これはOPの質問です)。そのような値を(たとえば、戻り値として、またはプロパティとして)公開すると、その値が予期せず変更された場合、問題のデバッグが非常に困難になる可能性があります。変更可能な値が共有されるため、これは内部と外部の両方のミューテーションに適用されます。
NSMutableArray
変数に割り当てるだけで十分です。オブジェクトが変更可能な配列になることを決して止めなかったので、オブジェクトで変更メソッドを呼び出すと、成功し、共有データが変更されます。一方、元の可変配列がコピーされて(不変配列に変更されて)NSMutableArray
変数に割り当てられ、その上で変更メソッドが呼び出された場合、変更doesNotRespondToSelector
メソッド呼び出しを受け取ったオブジェクトが事実、不変であり、これらのメソッドに応答しません。
可変性を介して配列を作成していて、不変バージョンを返したい場合は、継承によって可変配列を「NSArray」として返すだけです。
- (NSArray *)arrayOfStrings {
NSMutableArray *mutableArray = [NSMutableArray array];
mutableArray[0] = @"foo";
mutableArray[1] = @"bar";
return mutableArray;
}
呼び出し元を "信頼"して(技術的にはまだ変更可能)戻りオブジェクトを不変のNSArrayとして扱う場合、これはよりも安価なオプションです[mutableArray copy]
。
受信したオブジェクトを変更できるかどうかを判断するには、メッセージの受信者が戻り値の正式な型に依存する必要があります。たとえば、不変として型指定された配列オブジェクトを受け取った場合、それを変更しようとするべきではありません。クラスメンバーシップに基づいてオブジェクトが変更可能かどうかを判断することは、許容できるプログラミング方法ではありません。
上記の方法については、ここで詳しく説明します。
ベストプラクティス:戻り値の型がNSArrayの場合はmutableArray.copyまたはmutableArrayを返します
NSArray *array = [mutableArray copy];