4일 전에 코코아 프로그래밍 3판에 관한 질문 중 다음과 같은 질문을 받았습니다.
“번역판 62쪽 다섯 번째 줄에 “또한 어떤 초기화 메서드들은 리시버가 아닌 객체를 리턴하기도 한다” 라는 문장이 있습니다. 원서와 대조해보니 원서(56쪽)에는 없는 문장이더군요. 이것은 역자 주인가요? 그리고 그 의미는 [Foo init] 을 했을 때 Foo가 아닌 다른 클래스, Bar의 인스턴스가 리턴되는 경우도 있다는 의미인가요?” - W님
2판에 있던 내용을 원 저자가 3판에선 빼버린 내용인데, 왜 뺐는지 모르겠습니다. 저의 실수로 3판 원서와 완전히 동일하게 번역이 안되서 2판 내용을 재활용(…)하던 과정에서 첨가된 내용인데, 틀린 말은 아닙니다. 맞는 말입니다.
W님이 질문하신대로 [Foo init] 을 했을때 Foo 가 아닌 다른 클래스, Bar 의 인스턴스가 리턴되는 경우도 있다라는게 조금 다르긴한데, 거의 맞게 생각하신 겁니다. 이해하기 편하게 조금 더 용어들을 명확하게 할게요. Foo 라는 클래스가 있습니다. 그래서
foo = [[Foo alloc] init];
와 같이 foo 라는 인스턴스를 새로 생성합니다. 앞에서 [Foo alloc] 을 하게되면 Foo 란 클래스의 인스턴스가 하나 생겨납니다. 여기까진 Foo 클래스의 인스턴스임이 확실합니다. alloc 메시지가 하는 일은 메모리에서 할당을 하고, 모든 인스턴스 변수들을 초기화(0이나 0.0, NULL, 혹은 nil 등으로..)하고 isa 인스턴스 변수를 alloc 한 클래스를 가리키도록 초기화합니다. 그런데 이렇게해서 얻어진 인스턴스에 init 메시지를 보낼 경우에 init 메시지를 받은 리시버, 즉 alloc 으로 할당된 녀석이 리턴될 수도 있지만 alloc 으로 할당된 녀석이 아닌, 다른 녀석이 리턴될 수도 있다는 얘기입니다. 진하게 표시한 부분이 질문에 대한 답이 되겠지요?
다음의 코드를 살펴볼게요.
- (id)initWithAccountID:(NSString *)identifier {
if ( self = [super init] ) {
Account *ac = [accountDictionary objectForKey:identifier];
if (ac) { // object with that ID already exists
[self release];
return [ac retain];
}
if (identifier) {
accountID = [identifier copy]; // accountID is instance variable
[accountDictionary setObject:self forKey:identifier];
return self;
} else {
[self release];
return nil;
}
} else
return nil;
}
애플의 문서에서 가져온 코드인데.. 위와 같은 초기화 메서드를 작성했을 경우, 분명 init 메시지는 alloc 으로 할당한 녀석, 즉 리시버에게 보냈지만 리턴되는 객체는 리시버가 아닌, 기존에 다른 곳에서 할당했던 객체가 리턴되겠지요?
이 정도면 답변이 되었을까요? 음. 역주를 달았어야 했는데, 조금 아쉽네요.
이 애플 문서를 참고하시면 더 많은 도움이 되리라 봅니다. (영어 울렁증 있으신 분들은 패스!!)
p.s. 댓글로 무명(guest)님이 글을 달아주셨는데, 댓글로 다시 답글을 달긴 했지만 오해의 소지가 있어서 글에 덧붙입니다. Foo 란 클래스에 init 요청을 했는데 Bar 의 인스턴스를 리턴해버리면 안되겠지요. 당연한 얘기라 따로 언급을 안했는데 오해하신 분이 있네요. 제가 쓴 글의 요지는 “리시버가 아닌 다른 객체가 리턴될 수 있다”를 말한거구요. 물론 다른 객체라는 것도 Foo 클래스의 다른 객체이지, 전혀 새로운 Bar를 리턴하는건 아닙니다. 질문하신 분도 그 점은 알고 계셔서 뭔가 이상하다 생각하셔서 질문하신거고, 그런 상황이 아님을 알려드린 겁니다~ 오해하지 마세요
Recent Comments