Мне нужно сохранить свой собственный созданный класс в файл, я обнаружил в Интернете, что хорошим подходом является использование NSKeyedArchiver и NSKeyedUnarchiver
Мое определение класса выглядит так:
@interface Game : NSObject <NSCoding> {
NSMutableString *strCompleteWord;
NSMutableString *strWordToGuess;
NSMutableArray *arGuessedLetters; //This array stores characters
NSMutableArray *arGuessedLettersPos; //This array stores CGRects
NSInteger iScore;
NSInteger iLives;
NSInteger iRocksFallen;
BOOL bGameCompleted;
BOOL bGameOver;
}
Я реализовал методы initWithCoder:
и encodeWithCoder:
следующим образом:
- (id)initWithCoder:(NSCoder *)coder
{
if([coder allowsKeyedCoding])
{
strCompleteWord = [[coder decodeObjectForKey:@"CompletedWord"] copy];
strWordToGuess = [[coder decodeObjectForKey:@"WordToGuess"] copy];
arGuessedLetters = [[coder decodeObjectForKey:@"GuessedLetters"] retain];
// arGuessedLettersPos = [[coder decodeObjectForKey:@"GuessedLettersPos"] retain];
iScore = [coder decodeIntegerForKey:@"Score"];
iLives = [coder decodeIntegerForKey:@"Lives"];
iRocksFallen = [coder decodeIntegerForKey:@"RocksFallen"];
bGameCompleted = [coder decodeBoolForKey:@"GameCompleted"];
bGameOver = [coder decodeBoolForKey:@"GameOver"];
}
else
{
strCompleteWord = [[coder decodeObject] retain];
strWordToGuess = [[coder decodeObject] retain];
arGuessedLetters = [[coder decodeObject] retain];
// arGuessedLettersPos = [[coder decodeObject] retain];
[coder decodeValueOfObjCType:@encode(NSInteger) at:&iScore];
[coder decodeValueOfObjCType:@encode(NSInteger) at:&iLives];
[coder decodeValueOfObjCType:@encode(NSInteger) at:&iRocksFallen];
[coder decodeValueOfObjCType:@encode(BOOL) at:&bGameCompleted];
[coder decodeValueOfObjCType:@encode(BOOL) at:&bGameOver];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
if([coder allowsKeyedCoding])
{
[coder encodeObject:strCompleteWord forKey:@"CompleteWord"];
[coder encodeObject:strWordToGuess forKey:@"WordToGuess"];
[coder encodeObject:arGuessedLetters forKey:@"GuessedLetters"];
//[coder encodeObject:arGuessedLettersPos forKey:@"GuessedLettersPos"];
[coder encodeInteger:iScore forKey:@"Score"];
[coder encodeInteger:iLives forKey:@"Lives"];
[coder encodeInteger:iRocksFallen forKey:@"RocksFallen"];
[coder encodeBool:bGameCompleted forKey:@"GameCompleted"];
[coder encodeBool:bGameOver forKey:@"GameOver"];
}
else
{
[coder encodeObject:strCompleteWord];
[coder encodeObject:strWordToGuess];
[coder encodeObject:arGuessedLetters];
//[coder encodeObject:arGuessedLettersPos];
[coder encodeValueOfObjCType:@encode(NSInteger) at:&iScore];
[coder encodeValueOfObjCType:@encode(NSInteger) at:&iLives];
[coder encodeValueOfObjCType:@encode(NSInteger) at:&iRocksFallen];
[coder encodeValueOfObjCType:@encode(BOOL) at:&bGameCompleted];
[coder encodeValueOfObjCType:@encode(BOOL) at:&bGameOver];
}
}
И я использую эти методы для архивирования и разархивирования данных:
[NSKeyedArchiver archiveRootObject:currentGame toFile:strPath];
Game *currentGame = [NSKeyedUnarchiver unarchiveObjectWithFile:strPath];
У меня две проблемы.
1) Как видите, строки с arGuessedLettersPos
комментируются, потому что каждый раз, когда я пытаюсь кодировать этот массив, возникает ошибка (этот архиватор не может кодировать структуры), и этот массив используется для хранения структур CGRect.
Я видел решение в интернете. Дело в том, что каждый CGRect
в массиве преобразуется в NSString
(используя NSStringFromCGRect()
) и затем сохраняется. Это хороший подход?
2) Это большая проблема для меня. Даже если я прокомментирую эту строку и затем успешно выполню код, затем сохраню (заархивирую) данные и затем попытаюсь загрузить (разархивировать) их, данные не загружаются. Там нет никаких ошибок, но currentGame
объект не имеет данных, которые должны быть загружены.
Не могли бы вы дать мне совет? Я впервые использую архиваторы и разархиваторы.
Большое спасибо за каждый ответ.