문제

나는 싱글 톤으로 만든 수업을 가지고 있고 nskeyedarchiver를 사용하여 상태를 저장할 수 있지만 머리를 뒤로 당기는 데 머리를 감싸지 못합니다.

내가 가진 로딩을하는 함수에서

Venue *venue = [Venue sharedVenue];
NSData *data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
venue = [unarchiver decodeObjectForKey:@"Venue"];
[unarchiver finishDecoding];

이 코드를 사용하면 DecodeObjectForKey가 무엇을 반환합니까? 그것은 실제로 장소의 또 다른 사례가 될 수 없으며 저장된 값으로로드하지 않습니다. 싱글 톤 절약으로 변환하기 전에로드가 잘 작동했습니다.

도움이 되었습니까?

해결책

여기에 이것이 잘못되고 있다고 생각합니다. NSCODING에 익숙하며 일반적으로 vordewithCoder를 통해 객체를 코딩 할 수있게하여이를 채택합니다. 이것을 더 간단하게 만드는 것은 해당 메소드를 무시하지 않고도 NSCoding 및 NSCoder를 사용할 수 있다는 것입니다. 공유 OBEJCT 자체를 인코딩하지 않고 공유 객체의 상태를 인코딩 할 수 있습니다. 이것은 공유 객체를 디코딩하는 어색한 질문을 방지합니다.

다음은 내가 할 수있는 일의 예입니다.

@implementation MySharedObject
+ (id)sharedInstance {
    static id sharedInstance = nil;
    if (!sharedInstance) {
        sharedInstance = [[MyClass alloc] init];
    }
}

- (id)init {
    if ((self = [super init])) {
        NSData *data = /* probably from user defaults */
        if (data) { // Might not have any initial state.
            NSKeyedUnarchiver *coder = [[[NSKeyedUnarchiver alloc] initForReadingWithData:data] autorelease];
            myBoolean = [coder decodeBoolForKey:@"MyBoolean"];
            myObject = [[coder decodeObjectForKey:@"MyObject"] retain];
            [coder finishDecoding];
        }
    }
    return self;
}

- (void)saveState {
    NSMutableData *data = [NSMutableData data];
    NSKeyedArchiver *coder = [[[NSKeyedArchiver alloc] initForWritingWithMutableData:data] autorelease];
    [coder encodeBool:myBoolean forKey:@"MyBoolean"];
    [coder encodeObject:myObject forKey:@"MyObject"];
    [coder finishEncoding]
    // Save the data somewhere, probably user defaults...   
}
@end

여기에는 공유 객체가 있으며, 키드 아카이브를 사용하여 구성을 유지하지만 공유 객체 자체를 인코딩하지는 않습니다. 이것은 싱글 톤 클래스의 두 번째 인스턴스를 디코딩하는 어색한 질문을 피합니다.

다른 팁

싱글 톤 자체에서 로딩을 수행해야합니다. 여기서 일어나는 일은 싱글을 만들고, 싱글 톤에 LVAL을 할당 한 다음 새 객체를 만들고 싱글 톤을 수정하지 않고 LVAL을 해당 새로운 객체에 재 할당하는 것입니다. 다시 말해:

//Set venue to point to singleton
Venue *venue = [Venue sharedVenue];

//Set venue2 to point to singleton
Venue *venue2 = [Venue sharedVenue];

NSData *data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];

//Set venue to unarchived object (does not change the singleton or venue2)
venue = [unarchiver decodeObjectForKey:@"Venue"];
[unarchiver finishDecoding];

당신이하고 싶은 것은 이것을 주식에서 다루는 것입니다. 사람들이 싱글 톤을하는 방법에는 몇 가지가 있습니다. 그래서 나는 당신이 무엇을하고 있는지 확신 할 수 없지만 현재 ShareDvenue가 다음과 같은 것처럼 보입니다.

static Venue *gSharedVenue = nil;

- (Venue *) sharedVenue {
  if (!gSharedVenue) {
    gSharedVenue = [[Venue alloc] init];
  }

  return gSharedVenue;
}

그것이 객체를 전역의 싱글 톤에로드하기 위해 그것을 변경하려는 경우라고 가정합니다.

static Venue *gSharedVenue = nil;

- (Venue *) sharedVenue {
  if (!gSharedVenue) {
    NSData *data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]];
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    [data release];

    gSharedVenue = [unarchiver decodeObjectForKey:@"Venue"];
    [unarchiver finishDecoding];
    [unarchiver release];
  }

  if (!gSharedVenue) {
    gSharedVenue = [[Venue alloc] init];
  }

  return gSharedVenue;
}

분명히 어떻게 든 실제 경로를 보관 된 개체 파일로 전달해야합니다.

주석에 따라 편집 :

자, Alloc 기반 싱글 톤을 사용하는 경우 클래스 init 메소드 에서이 작업을 처리해야합니다.

- (id) init {
  self = [super init];

  if (self) {
    NSData *data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]];
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    [data release];

    Venue *storedVenue = [unarchiver decodeObjectForKey:@"Venue"];
    [unarchiver finishDecoding];
    [unarchiver release];

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

  }

  return self;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top