2010-01-28 2 views
3

Iphone SDK 3.1.2 사용. NSKeyedArchiver 개체를 사용하여 일부 정보를 파일에 저장하고 있습니다. 나는 4 개의 열쇠가있다. applicationDidFinshLaunching에있는 4 개의 키 모두에 대한 파일의 데이터를 읽고 applicationDidTerminate의 파일 (전체 4 키)에 다시 쓰십시오. 또한 사용자가 정보를 저장하면 특정 키의 데이터를 기록합니다.NSKeyedArchiver 파일 - 데이터 손실

처음에는 파일이 없기 때문에 계정 목록에 대한 배열을 할당합니다. 계정을 추가 할 수 있습니다.

파일에 저장된 데이터가 주기적으로 손실되는 문제가 있습니다. 가끔 accountlist에 영향을 미치는 하나의 키, 때로는 즐겨 찾기 목록입니다. 모든 4와 반대로 1key를 저장하면 악화 될 것 같습니다. ive는 organsier 을 사용하여 파일을 보았고 실제로 데이터가 누락되었습니다. 것은 그것이 작동하지 않는 많은 시간이다. 나는 왜 그렇게 모순되지 않습니다. 또한 내가 xcode에서 디버거를 termintate 경우에만 최근의 변경 사항을 잃지 않을 것으로 예상되는 전체 파일 데이터 whihc 일어날 것 같습니다. 전체 NSKeyedArchiv 어 물건은 어쩌면 또 다른 영구 저장 전략을 고려하여 너무 flakey 보인다. 누구나 이런 식으로 만날 수 있습니다.

- (void)viewDidLoad 
{ 

if(self.accountList == nil) 
{ 
    NSMutableArray *array = [[NSMutableArray alloc] init]; 
    self.accountList = array; 
    [array release]; 
} 

if(self.phoneSettings == nil) 
{ 
PhoneSettings* mySettings = [[PhoneSettings alloc] initSettings]; 
self.phoneSettings = mySettings; 
[mySettings release]; 
} 



NSString *filePath = [self dataFilePath]; 
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) { 
    NSData *data = [[NSMutableData alloc] 
        initWithContentsOfFile:[self dataFilePath]]; 
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] 
            initForReadingWithData:data]; 
    NSMutableArray *archiveArray = [unarchiver decodeObjectForKey:kDataKey]; 
if(archiveArray != nil) 
    self.accountList = [archiveArray retain]; 
else 
    LOG("No archived accounts"); 

NSMutableArray *archiveCallList = [unarchiver decodeObjectForKey:kCallListKey]; 
    if(archiveCallList !=nil) 
    appDelegate.callList = [archiveCallList retain]; 

    NSMutableArray *archiveFavouritesList = [unarchiver decodeObjectForKey:kfavouritesKey]; 
    if(archiveFavouritesList != nil) 
    appDelegate.favouritesList = [archiveFavouritesList retain]; 

    PhoneSettings* archiveSettings = [unarchiver decodeObjectForKey:kPhoneSettings]; 
    if (archiveSettings != nil) 
    self.phoneSettings = [archiveSettings retain]; 

    [unarchiver finishDecoding];   
    [unarchiver release]; 
    [data release]; 
} 

다음

- (void)applicationWillTerminate:(NSNotification *)notification { 

LOG("Application terminating"); 
SessionTalkAppDelegate* appDelegate = (SessionTalkAppDelegate*)[[UIApplication sharedApplication] delegate]; 




NSMutableData *data = [[NSMutableData alloc] init]; 
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] 
          initForWritingWithMutableData:data]; 
[archiver encodeObject:self.accountList forKey:kDataKey]; 
[archiver encodeObject:appDelegate.callList forKey:kCallListKey]; 
[archiver encodeObject:appDelegate.favouritesList forKey:kfavouritesKey]; 
[archiver encodeObject:self.phoneSettings forKey:kPhoneSettings]; 
[archiver finishEncoding]; 

[data writeToFile:[self dataFilePath] atomically:YES]; 
    [archiver release]; 
[data release];  
} 

답변

4

에 당신은 그 정도 코드가 필요하지 않습니다. 파일이 유효한 아카이브를 포함하지 않는 경우 {A @try에 전화를 묶어야한다, 그래서 NSKeyedUnarchiver는 NSInvalidArgumentException을 올릴 수

NSMutableDictionary *appState = [NSKeyedUnarchiver unarchiveObjectWithFile: [self dataFilePath]]; 

참고 :

NSMutableDictionary *appState = [NSMutableDictionary dictionary]; 
[appState setObject: self.accountList forKey: kDataKey]; 
[appState setObject: appDelegate.callList forKey: kCallListKey]; 
[appState setObject: self.phoneSettings forKey: kPhoneSettings]; 
if ([NSKeyedArchiver archiveRootObject: appState toFile: [self dataFilePath]] == NO) 
    NSLog(@"Failed to archive %@", appState); 

데이터를 읽어 데이터를 저장 } 블록.

+0

안녕하세요, 감사합니다.하지만 위의 코드는 계정 목록 만 보관했으며 다른 목록은 3 개 있습니다. 내가 무엇을해야합니까? Thanks again – tech74

+0

일반적으로 저장할 데이터가 들어있는 NSDictionary (또는 NSMutableDictionary)를 만듭니다. 그런 다음 사전을 NSKeyedArchiver에 대한 루트 객체로 전달하고 NSKeyedUnarchiver에서 다시 가져옵니다. 위에 게시 된 답변을 수정했습니다. – Costique

+0

감사합니다. 사용자가 저장을 클릭 할 때 앱 중에 통화 목록을 말하면 하나의 키만 저장한다고 가정하면 다음과 같습니다. NSMutableDictionary * appState = [NSMutableDictionary dictionary]; [appState setObject : appDelegate.callList forKey : kCallListKey]; (NSKeyedArchiver archiveRootObject : appState toFile : [self dataFilePath]] == NO) NSLog (@ "% @", appState를 아카이브하지 못했습니다. – tech74