NSMutableArray를 NSArray로 어떻게 변환합니까?


답변:


511
NSArray *array = [mutableArray copy];

Copy불변 사본을 만듭니다. Apple이 다양한 최적화를 할 수 있기 때문에 이것은 매우 유용합니다. 예를 들어 copy불변 배열로 전송 하면 객체 만 유지되고을 반환합니다 self.

가비지 수집 또는 ARC를 사용하지 않으면 -copy개체 를 유지 한다는 것을 기억하십시오 .


2
이 답변은 훌륭하지만 copyNSMutableArray가 아닌 일반 NSArray 를 만드는 문서에서 어떻게 알 수 있습니까?
Dan Rosenstark

22
@Yar : 당신은 볼 의 문서 NSCopying 이이 상태 : copyWithZone 고려 "불변 대 변경할 수는"수신 객체에 적용되는 경우 반환되는 복사는 불변이다; 그렇지 않으면 사본의 정확한 특성은 클래스에 의해 결정됩니다.
게오르그 lly 리

1
매우 깔끔합니다-나는 이것을 m5h의 솔루션보다 선호합니다. 간결하고 더 효율적입니다.
David Snabel-Caunt

1
David가 동의하며이 응답을 가리 키도록 응답을 업데이트했습니다.
hallski

2
@ 브래드 : 그것은 단지 변경 가능하고 변경 불가능한 구현을 가진 클래스를 의미합니다. 예 : NSArray& NSMutableArray, NSString& NSMutableString. 그러나 NSViewController항상 변경 가능한 상태를 포함하는 것은 아닙니다.
Georg Schölly

361

NSMutableArray하위 클래스 NSArray이므로 항상 변환 할 필요는 없지만 배열을 수정할 수 없도록 NSArray하려면 자동 릴리스 여부에 따라 다음 방법 중 하나를 만들 수 있습니다 .

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

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

편집 : Georg Schölly가 제공하는 솔루션 은 더 나은 방법이며 훨씬 깨끗합니다. 특히 ARC가 있고 자동 릴리스를 호출 할 필요가 없기 때문에 더욱 그렇습니다.


7
그냥 (NSArray *) myMutableArray 할 수 있습니까?
Vojto

2
예, NSMutableArray는 유효한 NSArray의 하위 클래스이므로
hallski

4
그러나 (NSArray *)로 캐스트해도 여전히 (NSMutable *)로 캐스트 할 수 있습니다. 그렇지 않습니까?
sharvey 2011

1
@sharvey : 네, 맞습니다. 캐스트하지 않고 서브 클래스에 직접 슈퍼 클래스를 할당하면 경고가 표시됩니다. 일반적으로 불변 복사본을 반환하려고합니다. 이것은 유일한 방법이므로 배열이 실제로 수정되지 않기 때문입니다.
Georg Schölly

1
이전 "Upcasting"(NSArray를 *) myMutableArray 및 역으로 알려진의는 "Downcasting"라고 그건
시스코 구티에레스

113

나는 두 가지 주요 솔루션을 모두 좋아합니다.

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]도 빈 배열을 반환합니다.
durazno

@durazno 잘못이 아닙니다. 테스트를 다시 확인하십시오. [mutableArray copy]가 빈 배열을 반환하는 경우 mutableArray는 빈 배열이어야합니다. 내 대답은 mutableArray가 nil 일 때만 적용됩니다.
Richard Venable

이것이 사실이지만, 당신의 모범에서 더 근본적인 진실을 놓치고 있다고 생각합니다. mutableArray를 nil로 할당 했으므로로 [mutableArray copy]단순화 할 수 있습니다 [nil copy]. objective-c 에서 nil로 전송 된 모든 메시지는 항상 nil입니다. "아무것도"와 "아무것도없는 배열"의 차이를 기억하는 것이 중요합니다.
mkirk

@mkirk "NSMutableArray를 NSArray로 어떻게 변환합니까?" 두 가지 주요 솔루션이 있으며, 그 사이의 주요 차이점은 가변 배열이 0 일 때 작동 방식입니다.
Richard Venable

18

이 코드를 사용해보십시오 ---

NSMutableArray *myMutableArray = [myArray mutableCopy];

NSArray *myArray = [myMutableArray copy];

다른 사람들이하지 않는 것은 무엇입니까?
Ben Leggiero

5

목표 -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

스위프트 부분은 전적으로 옳지 않습니다. 참조 여기여기에 가변 / 불변의 차이에 대한 Arrays와 NSArray/ NSMutableArrays의. 그들은 동일하지 않습니다.
Bruno Ely

3

objective-c에서 :

NSArray *myArray = [myMutableArray copy];

신속하게 :

 var arr = myMutableArray as NSArray

2
NSArray *array = mutableArray;

[mutableArray copy]반 패턴은 모든 샘플 코드에 적용됩니다. 과도하고 현재 범위의 끝에서 할당이 취소되는 가변 가변 배열의 경우 중지하십시오.

런타임에서 범위를 벗어나려고하고 0으로 선언되고 할당 해제 된 변경 가능한 배열의 낭비적인 복사를 최적화 할 수있는 방법은 없습니다.


변수에 변수 NSMutableArray를 할당하면 NSArray변수가 적용되지 않습니다 (OP의 질문입니다). 이러한 값 (예 : 반환 값 또는 속성)을 노출하면 해당 값이 예기치 않게 변경되면 문제를 디버깅하기가 매우 어려울 수 있습니다. 변경 가능한 값이 공유되므로 내부 및 외부 돌연변이에 모두 적용됩니다.
David Rönnqvist

해당 배열을 변경하려면 [NSMutableArray arrayWithArray : ... 또는 이와 유사한 형식이어야합니다.
Anton Tropashko

반드시 그런 것은 아닙니다. 단순히 NSMutableArray변수에 할당하는 것으로 충분합니다. 객체가 변경 가능한 배열이되는 것을 멈추지 않았으므로 mutating 메소드를 호출하면 성공하고 공유 데이터가 변경됩니다. 반면에 원래의 가변 배열을 변경 불가능한 배열로 변경 한 다음 NSMutableArray변수에 할당하고 그에 대한 변환 메소드를 호출 한 경우, doesNotRespondToSelectormutating 메소드 호출을 수신 한 오브젝트가 사실은 불변이며 그 방법에 응답하지 않습니다.
David Rönnqvist

오케이, 이것은 타이포 변환 어설 션에 대한 컴파일러 경고에주의를 기울이지 않는 개발자들에게 약간의 장점이있을 수 있습니다.
Anton Tropashko

1

가변성을 통해 배열을 생성 한 다음 불변 버전을 반환하려는 경우 상속을 통해 가변 배열을 "NSArray"로 간단히 반환 할 수 있습니다.

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

    return mutableArray;
}

(기술적으로 여전히 변경 가능한) 반환 객체를 불변의 NSArray로 취급하기 위해 호출자를 "신뢰"하는 경우,이 방법이보다 저렴 [mutableArray copy]합니다.

애플은 동의한다.

수신 된 오브젝트를 변경할 수 있는지 여부를 판별하려면 메시지 수신자는 공식적인 리턴 값 유형에 의존해야합니다. 예를 들어 불변으로 입력 된 배열 객체를 받으면이를 변경 하지 않아야합니다 . 클래스 멤버쉽을 기반으로 객체가 변경 가능한지 여부를 결정하는 것은 허용되는 프로그래밍 관행이 아닙니다.

위의 연습은 여기에서 더 자세히 설명됩니다.

모범 사례 : 반환 유형이 NSArray 인 경우 mutableArray.copy 또는 mutableArray를 반환합니다.


0

나는 신속한 3의 답을 찾고 있었고이 질문은 검색의 첫 번째 결과로 나타 났으며 나는 그것에 대한 답을 얻었으므로 여기에는 신속한 3 코드가 있습니다.

let array: [String] = nsMutableArrayObject.copy() as! [String]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.