2009-09-22 4 views
7

내부적으로 NSMutableArray를 사용하여 새로 생성 된 NSArray 인스턴스를 반환하는 메서드가 있다고 가정 해 보겠습니다. 나는 종종Objective-C에서 반환 유형을주의 깊게 사용하고 계십니까?

- (NSArray *)someArray { 
    NSMutableArray *mutableArray = [[NSMutableArray new] autorelease]; 
    // do stuff... 
    return mutableArray; 
} 

개인적 :

- (NSArray *)someArray { 
    NSMutableArray *mutableArray = [[NSMutableArray new] autorelease]; 
    // do stuff... 
    return [NSArray arrayWithArray:mutableArray]; // .. or [[mutableArray copy] autorelease] 
} 

을 또는있는 NSMutableArray가있는 NSArray의 서브 클래스이기 때문에 그냥있는 그대로 가변 배열 객체를 떠나을 직접 반환 할 : 당신은 항상 같은 것을 할 마십시오 내가 "안전한"또는 더 "올바른"것 같은 기분이 들었 기 때문에이 메서드에서 반환 할 때 변경할 배열을 NSArray로 바꿉니다. 솔직히 말해서, NSArray에 캐스트 된 가변 배열을 반환하는 데 문제가 없었으므로 실제로는 문제가되지는 않을 것입니다. 그러나 이와 같은 상황에 가장 적합한 방법이 있습니까?

답변

9

이전에는 return [NSArray arrayWithArray:someMutableArray]을 사용했지만 천천히 실용적이지는 않습니다. API의 호출자가 반환 된 객체를 선언 된 클래스의 하위 클래스로 처리하는 경우 오류가 발생합니다.

[주의 사항 : 아래에 게시 된주의 사항 참조]

+1

나는 일반적으로 동의합니다. 그러나 반환 된 값으로 호출 코드를 처리 할 수있는 가능성이 심각한 문제를 일으킬 수있는 경우 방어 복사가 좋습니다. 이것은 특히 프레임 워크 코드에 해당됩니다. –

+0

호출 코드가 귀하의 API가 변하지 않는 것으로 처리되어야한다고 말하는 변이가 있다면, 그들은'-mutableCopy'를 수행해야합니다. 그렇지 않으면 잘못하고있는 것입니다. ;) (비록 당신이해야한다고 생각한다면 방어에서 당신을 막을 수 없다.) – Wevah

+4

진짜 문제는, 나중에 변이 될 수있는 배열에 변경 가능한 배열 참조를 반환하면 NSArray *를받는 호출자가 내용이 절대로 바뀌지 않는다고 가정하고 ... 잘 ... * 붐 (BOOM). – bbum

5

NSMutableArray 캐스트를 NSArray로 반환하는 것은 매우 일반적입니다. 필자는 대부분의 프로그래머가 불변의 객체를 다운 캐스팅하고 변형 시키면 더러운 버그를 도입 할 것이라는 것을 깨닫게 될 것이라고 생각한다.

또한 NSMutableArray ivar someMutableArray이 있고 KVC 접근 방법에서 [NSArray arrayWithArray:someMutableArray]을 반환하면 KVO가 엉망이 될 수 있습니다. "관찰자가 계속 붙어있는 상태에서 객체가 할당 해제되었습니다"오류가 발생합니다.

0

NSArray는 실제로 유형이 아닌 클래스 클러스터입니다. 그래서 어느 곳에서나 NSArray를 볼 수 있습니다. 이미 여러 가지 유형 중 하나 일 가능성이 있습니다. 따라서 'NSArray로 변환'은 다소 오해의 소지가 있습니다. NSMutableArray는 이미 NSArray 인터페이스를 준수하며, 이것이 가장 많이 처리 될 것입니다. 어떤 경우

CocoaObjects fundamentals

, 당신은 아마 배열이 가변인지 여부를 걱정할 필요가 없습니다 (오토 릴리즈에 감사하고 나중에 그것을 유지하지 않음) 배열을 반환하고 주어진.

그러나 배열을 유지한다면 클라이언트가 내용을 변경하지 못하도록 할 수 있습니다.

+1

NSArray 프로토콜이 없습니다. NSMutableArray는 NSArray 클래스의 하위 클래스입니다. –

+0

피터, 당신은 절대적으로 옳았습니다. 내 부분에서 실수였습니다. 거기에는 '인터페이스'가있었습니다. 그에 따라 내 대답을 업데이트했습니다. – AlBlue

관련 문제