2010-05-10 2 views
1

인스턴스를 얻으려면 보통/init처럼 할당하는 객체가 있습니다. 나중에 내 응용 프로그램에서 해당 개체에 대해 디스크에서 상태를로드하려고합니다. 나는 내 수업 (NSCoding을 준수)을 파기하고 내 인스턴스가 가리키는 곳을 바꿀 수 있다고 상상한다. 이 코드를 사용하여이를 ...에 자발적 포인터 변경

NSString* pathForDataFile = [self pathForDataFile]; 
if([[NSFileManager defaultManager] fileExistsAtPath:pathForDataFile] == YES) 
{ 
    NSLog(@"Save file exists"); 
    NSData *data = [[NSMutableData alloc] initWithContentsOfFile:pathForDataFile]; 
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; 
    [data release]; 

    Person *tempPerson = [unarchiver decodeObjectForKey:@"Person"]; 
    [unarchiver finishDecoding]; 
    [unarchiver release]; 

    if (tempPerson) 
    { 
     [self release]; 
     self = [tempPerson retain]; 
    } 
} 

지금 내 응용 프로그램 전반에 걸쳐 일부 NSLogs은 내가 무엇을 놓치고

self.person: <Person: 0x3d01a10> (After I create the object with alloc/init) 
self: <Person: 0x3d01a10> (At the start of this method) 
tempPerson: <Person: 0x3b1b880> (When I create the tempPerson) 
self: <Person: 0x3b1b880> (after i point self to the location of the tempPerson) 
self.person: <Person: 0x3d01a10> (After the method back in the main program) 

을 발견 뿌려 때?

답변

5

self은 인스턴스 메소드의 함수 인수입니다. self에 할당하는 것은 완벽하게 합리적입니다. 다른 함수 인수에 값을 할당하는 것이 완전히 합리적입니다. self의 범위가 현재 함수이기 때문에 코드에서 하나의 객체가 유출되어 충돌을 일으킬 수있는 방식으로 다른 객체를 릴리스합니다.

self에 의미가있는 유일한 시간은 init입니다. 거의 사용되지는 않지만 init 메서드는 자체를 해제하고 반환 할 새 객체를 할당하거나 nil을 반환 할 수 있습니다. 이 작동하는 유일한 이유는 반환 값이 self이고 호출자가 init이므로 반환 값을 사용하기 때문입니다.

올바른 방법은 인스턴스의 구성원을 대체하려고 시도하는 것이 아니라 인스턴스 구성원에게 새로운 값을 할당하는로드 함수입니다.

+0

두 가지 모두 우수한 답변입니다. 이 방법은 내 접근법이 왜 그렇게 잘못되었는지에 대한 배경을 좀 더 알려줍니다. 감사합니다! – rob5408

6

하지 마십시오. 아이덴티티 규칙을 위반하는 것 외에도 프로그램의 다른 부분이 갖는 포인터 값을 변경할 수 없습니다.

더 나은 접근법은 PIMPL 관용구를 사용하는 것입니다. 즉, 클래스가 구현 객체에 대한 포인터를 보유하고 있으며이를 바꾸는 것뿐입니다.

예.

@class FooImpl; 
@interface Foo { 
    FooImpl* impl; 
} 
// ... 
- (void)load; 
@end 

@implementation Foo 
- (void)load { 
    FooImpl* tmp = loadFromDisk(); 
    if (tmp) { 
     FooImpl* old = impl; 
     impl = tmp; 
     [old release]; 
    } 
} 
@end 
+0

고마워요! 나는 이것을 줄 것이다. – rob5408