web-dev-qa-db-ja.com

NSMutableArrayをNSArrayに変換する方法を教えてください。

NSMutableArrayをNSArrayに Objective-c で変換するにはどうすればよいですか?

373
marcy
NSArray *array = [mutableArray copy];

Copy は不変コピーを作成します。 Appleはさまざまな最適化を行うことができるので、これは非常に便利です。たとえば、copyを不変配列に送信してもオブジェクトは保持され、selfが返されるだけです。

ガベージコレクションまたはARCを使用しない場合は、-copyがオブジェクトを保持することを忘れないでください。

496
Georg Schölly

NSMutableArrayNSArrayのサブクラスなので、常に変換する必要はありませんが、配列を変更できないようにする場合は、自動解放するかどうかに応じて、次のいずれかの方法でNSArrayを作成できます。

/* Not autoreleased */
NSArray *array = [[NSArray alloc] initWithArray:mutableArray];

/* Autoreleased array */
NSArray *array = [NSArray arrayWithArray:mutableArray];

EDIT:解決策 GeorgSchöllyが提供したほうがより良い方法です。 ARCでも自動解放を呼び出す必要はありません。

359
hallski

私は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
112
Richard Venable

あなたはこのコードを試してみます---

NSMutableArray *myMutableArray = [myArray mutableCopy];

そして

NSArray *myArray = [myMutableArray copy];
18
Jerry Thomsan

Objective-C

下記は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
4
Sakir Sherasiya

目標-c:

NSArray *myArray = [myMutableArray copy];

Swiftでは

 var arr = myMutableArray as NSArray
3
Vikram Biwal
NSArray *array = mutableArray;

この[mutableArray copy] antipatternは、サンプルコード全体です。一時的で現在のスコープの最後で割り当て解除される、使い捨ての可変配列の場合は、そうしないでください。

ランタイムが範囲外になり、0に減り、適切に割り当て解除された可変配列の無駄なコピーを最適化する方法はありません。

2
Anton Tropashko

可変性によって配列を構築していて、不変バージョンを返したい場合は、継承によって可変配列を「NSArray」として単純に返すことができます。

- (NSArray *)arrayOfStrings {
    NSMutableArray *mutableArray = [NSMutableArray array];
    mutableArray[0] = @"foo";
    mutableArray[1] = @"bar";

    return mutableArray;
}

(技術的にはまだ変更可能な)戻りオブジェクトを不変のNSArrayとして扱うように呼び出し側を "信頼する"場合、これは[mutableArray copy]よりも安いオプションです。

アップルは同意します:

受信したオブジェクトを変更できるかどうかを判断するには、メッセージの受信側は戻り値の正式な型に依存しなければなりません。例えば、それが不変として型付けされた配列オブジェクトを受け取った場合、それを変更しようとするべきではありません。オブジェクトがそのクラスメンバーシップに基づいて変更可能であるかどうかを判断することは、許容できるプログラミング方法ではありません。

上記のプラクティスは、ここでさらに詳しく説明されています。

ベストプラクティス:戻り型がNSArrayの場合はmutableArray.copyまたはmutableArrayを返す

1
pkamb

私はSwift 3で答えを探していましたが、この質問は最初の検索結果として表示され、そこから答えを得たのでSwift 3のコードです。

let array: [String] = nsMutableArrayObject.copy() as! [String]
0
Amr Angry