nskeyedarchiver에서 싱글 톤의 상태를로드합니다
-
18-09-2019 - |
문제
나는 싱글 톤으로 만든 수업을 가지고 있고 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;
}