2013-12-15 1 views
3

(예 지정 초기화)에서 오브젝티브 C 인스턴스의 일반적인 초기화 시퀀스 등 간다 :자아 테스트는 여전히 필요하고 의미가 있습니까?

- (id)initWithFrame: (NSRect)frame { 
    self = [super initWithFrame: frame]; 
    if (self != nil) { 
    // Do your stuff. 
    } 
    return self; 
} 

이것은 잘 알려진 패턴이지만, 자기가 할당 된 경우 테스트 정말 필요한가? 내 말은, 어떤 것이 super 메소드에서 실패한다면, 단순히 nil을 리턴하는 것보다 예외를 발생시키지 않을 것인가? 그것은 안전한 패턴입니까? super 호출에 문제가 있지만 여전히 (임의의) 포인터를 반환하면 어떻게 될까요?

확실히 방어 프로그래밍의 문제이지만 실제로 아무런 결과도 없다는 것을 알고있는 경우 많은 테스트를 수행하는 것이 과장된 것입니다. 물론, 자체을 확인하는 것이 합리적 일 수 있습니다 (문서화해야 함).

+1

'nil'을 반환하면 여전히'init' 메소드가 아닌 예외가 발생합니다. – nhgrif

+0

예. 설립 된 국제 대회를 따르십시오. – uchuugaka

+0

'super '에 대한 호출에 문제가 있고'nil' 또는 유효한 포인터 대신에 가비지를 반환하면 그 코드에 심각한 버그가 있으며 개발자는 속여 야합니다. – rmaddy

답변

0

질문은 다음과 같이 요약됩니다. 이니셜 라이저에서 nil을 반환하는 알려진 클래스가 있습니까?

거의없는 것 같습니다. 물론 오류를 지적하기 위해 nil을 반환해야하는 알려진 경우 (생성자가 종종 NSError을 참조로 가져 오는 경우)가 있습니다.

그러나 대부분의 다른 초기화 프로그램은 self 인수 또는 클래스의 다른 인스턴스를 반환합니다. 그렇지 않은 경우 문서에서 명확하게 표현되어야합니다. 코드는 일반적으로 객체 생성에 의존하므로 실패하지 않습니다.

그래서 수퍼 클래스의 동작을 확인할 때 nil에 대한 테스트를 생략해도 안전하다고 생각합니다.

반면에 패턴은 매우 유사하여 공동 개발자가 누락에 대해 혼란 스러울 수 있으며이를 감독으로 지적 할 수 있습니다. 따라서 조건이없는 스타일로 전환하려는 경우 적어도 동료 개발자에게 어떻게 든 전달되어야합니다.

+0

그건 내가 생각하고 있던 라인을 따라있다. 결코 nil을 반환하지 않는 경우에 대한 할당을위한 검사가 너무 많습니다. CPU주기를 구울 수있는 더 좋은 방법이 있습니다. –

+2

"몇 가지"클래스 만 nil을 반환한다는 내용에 동의하지 않습니다. 예를 들어, UIView의 지정된 초기화 프로그램 (OP 질문과 마찬가지로'initWithFrame :')은 nil을 반환 할 수 있으므로 모든 UIView는 init 메서드에서 nil을 잠재적으로 반환 할 수 있습니다. 나는 그러한 경고가 없다는 것이 초기화가 실패 할 수 없다는 보장이라고 가정하는 것이 안전하다고 생각하지 않는 것이 일반적이라고 생각한다. –

+1

@JesseRusak 그러나 init의 대부분의 코드 *는 initWithFrame :이 nil을 반환 할 수 있다는 것을 알지 못합니다. 필연적으로 addSubview의 예외로 실행됩니다 : 여기서 nil 인수에 대해 불평합니다. 그러한 즉각적인 무심코 검사가 뒤 따르지 않는 경우에는 앱이 대개 예상대로 작동하지 않습니다. 따라서 init의 내부에서 충돌하는 것은 실제로 좋은 일이 될 수 있으며 디버깅을 쉽게 할 수 있습니다. –

3

무언가가 잘못되었을 때 objective-c 프로그램에서 예외를 제기하는 것이 합당한 행위가 아닙니다. throw 예외는 치명적이고 복구 불가능한 프로그래머 오류 상황에서만 사용해야합니다.

init 메서드에서 오류를 알리는 올바른 방법은 nil을 반환하고 선택적으로 전달 된 NSError 포인터에 자세한 정보를 입력하는 것입니다. _foo = 2 짧은 손이기 때문에 어떤 역 참조 것, self->_foo = 2, 이것은 슈퍼 초기화는 nil을 반환하는 경우 충돌합니다

@implementation { 
    int _foo; // instance variable 
} 

- (id)initWithFrame: (NSRect)frame { 
    self = [super initWithFrame: frame]; 
    if (self != nil) { 
    _foo = 2; 
    } 
    return self; 
} 

: 테스트는 슈퍼 초기화를 반환 전무는 쓸모 초기화를 수행에서 당신을 방지하고, 같이 가능한 충돌을 방지 할 수있는 경우 nil 포인터. (메시지 만 자기가 0 일 때 nil을 반환합니다. 직접 ivar에 액세스해도 직접적으로 보장되지 않습니다.)

+0

오류를 제기하는 대신 nil을 반환하는 것을 강력히 말하는 한 가지 사실은 Objective-C가 일반적으로하는 패러다임을 가지고 있다는 것입니다 확인하지 않아도됩니다. 어쩌면 이니셜 라이저의 체크가 그 가격인가? –

+0

이 질문은 예외 대 예외가 아니라고 생각합니다. 두 경우 모두 유효한 이유와 Apple 프레임 워크의 많은 예가 있습니다. 요지는 두 경우 모두 문서화해야하며 이유를 설명해야합니다. 수퍼 클래스에서'nil '이 반환 될 가능성이 있다면 분명히 조건을 생략 할 수 없습니다. –

2

일부 클래스는 심지어 Apple 고유의 NS 클래스도 이니셜 라이저에서 nil을 반환 할 수 있습니다. NSArray 및 NSDictionary의 initWithContentsOfFile:initWithContentsOfURL: 메소드 그 대신에 예외가 발생해야합니까? 아니! 쉽게 감지 할 수 있고 쉽게 복구 할 수 있습니다. 예외를 저지르는 것은 올바른 오류 검사를 수행하는 데 신경 쓸 수없는 게으른 프로그래머를위한 버팀목 일뿐입니다.

+0

nil을 반환하는 경우에는 당연히 이해가되지만 그 점은 아닙니다. 그것은 nil이 될 수 없다면 nil을 검사하는 것에 관한 것입니다 (예상하지 못하는 것은 nil을 리턴 할 수있는 것보다 훨씬 더 많습니다). –

관련 문제