#import <Foundation/Foundation.h>
@interface A : NSObject <NSCopying> { // NSCopying 프로토콜을 따른다.
int x;
}
-(void) setX:(int)_x;
-(int) x;
@end
@implementation A
-(void) setX:(int)_x
{
x = _x;
}
-(int) x
{
return x;
}
-(id)copyWithZone:(NSZone*)zone { // copyWithZone: 메소드의 구현
A* tempA = [[self class] allocWithZone:zone];
// 상속할 경우를 대비해서 A 클래스 이름을 직접 사용하는 대신 위와 같이 작성한다.
tempA->x = self->x;
return tempA;
}
@end
int main (int argc, const char * argv[]) {
A* A1 = [A alloc];
[A1 setX:10];
A* A2 = [A1 copy]; // 사용자 정의 객체의 깊은 복사
[A2 setX:20]; // 수정이 안되어야 하지 않나? mutable 이 아니니까.
printf("%d %dn", [A1 x], [A2 x]);
[A1 release];
return 0;
}
위 소스에서 제가 궁금한 부분은.
// 상속할 경우를 대비해서 A 클래스 이름을 직접 사용하는 대신 위와 같이 작성한다.
음... C++ 에서는 그냥 자기 이름으로 new 해도 별 탈 없었는데, (상속 있더라도)
왜 여기선 상속할 경우를 대비해서 그냥 쓰면 안돼? 만약 B 로 상속받으면 self class 가 B 로 바껴? 그게 더 이상한데.. ㅜㅜ
[A2 setX:20]; // 수정이 안되어야 하지 않나? mutable 이 아니니까.
mutableCopy 가 아니니까 수정이 안되어야 맞는거 아니야? 왜 수정해도 아무런 에러가 안나고 정상 작동하지.??
또, copy 된 대상은 release 메시지 안보내줘도 돼??
1. 그게 맞아. B가 A를 상속한다고 했지? B의 입장에서 copyWithZone:을 구현하려면, 1) 현재 클래스의 새로운 인스턴스를 만들고, 2) A 클래스에 정의된 필드를 복사한 다음에 3) B 클래스에만 정의된 필드를 복사해야돼지. 만약에 A 클래스에서 새로 만드는 객체의 타입을 고정해버린다면, 하위클래스에서 그렇게 구현한 코드를 가져다 쓸수가 없어. B타입 객체를 반환해야 하는데 복사된게 A타입이면, B 타입 객체를 하나 더 만들고 B 타입에 정의된 모든 필드들(A에 있는걸 포함해서)을 다시 다 복사해야겠지.
2. API를 잘못 이해한듯. 수정이 가능한 객체는 NSMutableCopying 프로토콜을 구현해야 하고, 수정이 불가능한 객체는 NSCopying을 구현해야됨. 그런걸 별로 따지고 싶지 않으면, NSCopying을 구현하셈. (
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Protocols/NSMutableCopying_Protocol/Reference/Reference.html)
3. 복사된 객체는 copy 메시지를 보낸 쪽에 해제할 책임이 있음. - A copy produced with NSCopying is implicitly retained by the sender, who is responsible for releasing it. (
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Protocols/NSCopying_Protocol/Reference/Reference.html#//apple_ref/occ/intf/NSCopying)
오 댓글 읽고 이해하려면 좀 있어야 겠다.. 고마워
1번은 직접 구현해보면 암. ㅎㅎ