2013-03-19 4 views
1

다른 방법으로 변수를 설정하는 것보다 나은 방법이라고 생각하기 때문에 객체에 대한 사용자 정의 이니셜 라이저를 작성했습니다. 이 이니셜 라이저에서는 보통 객체의 변수를 설정 한 다음 주 init에 호출을 반환합니다.사용자 정의 객체 초기화 도구

value
-(id)initWithValue:(int)val { 
    self.value = val; 
    return [self initWithNibName:nil bundle:nil]; 
} 

은의 ViewController 서브 클래스에 속하는 정수이고,보다 일반적으로 더 값이 있습니다

그래서, 예를 들어, UIViewController에 내 코드는 다음과 같을 것입니다 서브 클래스.

그러나 최근에 나는 self = [self init...]이 클래스의 현재 인스턴스를 대체 할 것이므로 자신의 인스턴스를 잃을 것이라고 생각하여 스스로 먼저 설정하기 시작했습니다. 그래서 나는 일을 시작했다 :

-(id)initWithValue:(int)val { 
    self = [self initWithNibName:nil bundle:nil]; 
    self.value = val; 
    return self; 
} 

은 그때 최근에 원래의 버전을 확인하고 모든 것이 제대로 작동 않음을 깨닫고 변화는 불필요한이었다.

그래서, 내 질문은 이것이다 :

  1. 뭐라고를 않습니다 [슈퍼 initWithNibName : 번들 :]는이 객체를 생성하지만, 원래 객체를 대체하지하는 원인이되는합니까?
  2. 두 버전 중 하나가 다른 버전보다 사용이 편리할까요? 하나가 더 좋은 경우 사용해야합니다.

고맙습니다.

답변

0

작성한 첫 번째 코드는 데이터를 저장하려는 개체를 만들기 전에 value을 저장하지 않습니다. 그러나, 두 번째 코드는이 같은 더 나은 연습 즉,을위한 작은 수정 ...이 당신에게 유용

-(id)initWithValue:(int)val { 
    self = [self initWithNibName:nil bundle:nil]; 

    if(self) 
    _value = val; 

    return self; 
} 

희망 ... :-)

+0

그게 내가 생각한 것인데 값을 설정하고, 다음에'self = [self initWithNibName : bundle :]'을 실행하여 값을 출력했다. 나는 자아가 항상 바뀌지는 않을 것이라고 추측하고 있지만, 일반적으로 당신의 방식대로하는 것이 더 안전합니다. – Jsdodgers

+0

또한 '_value'에 대한 팁을 보내 주셔서 감사합니다. 이 점에 대해 분명히하기 위해서,'_value'를 사용할 때,'[self setValue :]'는 호출되지 않을 것입니다, 맞습니까? 그렇다면 self.value를 사용하지 않는 유일한 이유가 있거나 다른 것이 있습니까? – Jsdodgers

+0

값이 귀하의 경우 속성이므로이 표준 코드와 같은 용도로 합성하는 동안 ... @ 합성 값 = _value; [self setValue :]를 사용하여 값을 가져올 수도 있습니다. –

1

필요에 다음 코드를 사용하십시오 init 메소드를 오버라이드

-(id)initWithValue:(int)val 
{ 
    self = [super init]; 
    if(self) 
    { 
    self.value = val; 
    } 

    return self; 
} 
0

[super initWithNibName : bundle :]이 실제로 수퍼 클래스의 메소드를 호출합니다. [self initWithNibName : bundle :]을 사용하면 실제로 initWithNibName : bundle :을 다시 작성해야합니다. 물론 다시 작성해야합니다. 그렇지 않으면 수퍼 클래스 메소드도 호출합니다. 그래서 initWithNibName의 재 작성에서 일부 초기화를 원한다면 [self initWithNibName : bundle :]을 사용할 수 있습니다. 그러나 추가 초기화가 필요 없다면 to 메소드와 아무런 차이가 없습니다.

2

당신은 그것을 다음과 같은 방법으로 수행해야합니다 아이폰 OS에서

- (id)initWithValue:(int)val { 
    self = [super initWithNibName:nil bundle:nil]; 
    if (self) { 
     _value = val; 
    } 
    return self; 
} 

을, 일반적인 패턴은 초기화 방법으로 전송 매개 변수가 유효하지 않은 경우 전무를 반환하는 것입니다. 값은 2 가지 중 하나입니다 : self 또는 nil에 대한 현재 포인터. super 호출이 nil을 반환하면 객체가 제대로 설정되지 않았으므로 nil도 반환해야합니다.self = [super initWithNibName : nil 번들 : nil]; 그냥 슈퍼가 반환 할 수있는 무효 값을 존중하는 것이 더 쉽다.

+0

'init' 메소드에서 다른 객체 ('nil' 또는'self'의 현재 값이 아닌)를 반환하는 것은 실제로 완벽하게 유효합니다. 이는 기존 객체를 새 객체로 대체하기 위해 수행됩니다. 예를 들어 펜촉이나 특정 하위 클래스 또는 싱글 톤에서로드 된 객체를 대체 할 수 있습니다. 이 객체를'self'에 저장하고'init' 메소드의 나머지 부분에서는 원래 인스턴스 대신 사용하십시오. –

+0

이들은 일반적으로 클래스 클러스터라고하며, 그 이유 때문에 클래스 클러스터를 서브 클래 싱해서는 안됩니다. self는 슈퍼 클래스의 다른 하위 클래스 유형이 될 가능성이 높습니다. 따라서 현재 클래스에서 메서드 및 인스턴스 변수에 액세스하면 EXC_BAD_ACCESS가됩니다. –

+0

Nick, 클래스 클러스터는 수퍼 클래스가 다른 인스턴스를 반환 할 수있는 여러 가지 이유 중 하나입니다 '-init'에서. Mike Ash의 기사 [코코아 이니셜 라이저의 방법 및 이유] (http://www.mikeash.com/pyblog/the-how-and-why-of-cocoa-initializers.html), 특히 신화/사실 섹션 , 상세 사항은. –