iPhone-自定义对象的存档阵列
我已经试了几个小时了,但我解决不了这个问题 我正在制作一个保存未完成的国际象棋游戏的应用程序,所以我正在尝试将一个数组写入一个文件 这就是数组的含义(如果有意义的话):iPhone-自定义对象的存档阵列,iphone,objective-c,xcode,sdk,Iphone,Objective C,Xcode,Sdk,我已经试了几个小时了,但我解决不了这个问题 我正在制作一个保存未完成的国际象棋游戏的应用程序,所以我正在尝试将一个数组写入一个文件 这就是数组的含义(如果有意义的话): -NSMutableArray savedGames --GameSave a ---NSMutableArray board; ----Piece a, b, c, etc. -----some ints ---NSString whitePlayer, blackPlayer; ---int playerOnTop, tur
-NSMutableArray savedGames
--GameSave a
---NSMutableArray board;
----Piece a, b, c, etc.
-----some ints
---NSString whitePlayer, blackPlayer;
---int playerOnTop, turn;
--GameSave b
---NSMutableArray board;
----Piece a, b, c, etc.
-----some ints
---NSString whitePlayer, blackPlayer;
---int playerOnTop, turn;
等等
以下是我的NSCoding方法:
GameSave.m
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:whitePlayer forKey:@"whitePlayer"];
[coder encodeObject:blackPlayer forKey:@"blackPlayer"];
[coder encodeInt:playerOnTop forKey:@"playerOnTop"];
[coder encodeInt:turn forKey:@"turn"];
[coder encodeObject:board forKey:@"board"];
}
- (id)initWithCoder:(NSCoder *)coder {
self = [[GameSave alloc] init];
if (self != nil)
{
board = [coder decodeObjectForKey:@"board"];
whitePlayer = [coder decodeObjectForKey:@"whitePlayer"];
blackPlayer = [coder decodeObjectForKey:@"blackPlayer"];
playerOnTop = [coder decodeIntForKey:@"playerOnTop"];
turn = [coder decodeIntForKey:@"turn"];
}
return self;
}
一件
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeInt:color forKey:@"color"];
[coder encodeInt:piece forKey:@"piece"];
[coder encodeInt:row forKey:@"row"];
[coder encodeInt:column forKey:@"column"];
}
- (id)initWithCoder:(NSCoder *)coder {
self = [[Piece alloc] init];
if (self != nil)
{
color = [coder decodeIntForKey:@"color"];
piece = [coder decodeIntForKey:@"piece"];
row = [coder decodeIntForKey:@"row"];
column = [coder decodeIntForKey:@"column"];
}
return self;
}
这是尝试存档并保存到文件的代码:
- (void)saveGame {
ChessSaverAppDelegate *delegate = (ChessSaverAppDelegate *) [[UIApplication sharedApplication] delegate];
[[delegate gameSave] setBoard:board];
NSMutableArray *savedGames = [NSKeyedUnarchiver unarchiveObjectWithFile:[self dataFilePath]];
if (savedGames == nil) {
[NSKeyedArchiver archiveRootObject:[delegate gameSave] toFile:[self dataFilePath]];
} else {
[savedGames addObject:[delegate gameSave]];
[NSKeyedArchiver archiveRootObject:savedGames toFile:[self dataFilePath]];
}
}
- (NSString *)dataFilePath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:@"gameSaves.plist"];
}
抱歉,问题出在这里:
设置一些断点后,在-saveGame:[NSKeyedArchiver archiveRootObject:savedGames-toFile:[self-dataFilePath]] 这就是控制台中显示的内容:
2010-05-11 17:04:08.852 ChessSaver[62065:207] *** -[NSCFType encodeWithCoder:]: unrecognized selector sent to instance 0x3d3cd30
2010-05-11 17:04:08.891 ChessSaver[62065:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFType encodeWithCoder:]: unrecognized selector sent to instance 0x3d3cd30'
2010-05-11 17:04:08.908 ChessSaver[62065:207] Stack: (
32339035,
31077641,
32720955,
32290422,
32143042,
238843,
25827,
238843,
564412,
342037,
238843,
606848,
17686,
2733061,
4646817,
2733061,
3140430,
3149167,
3144379,
2837983,
2746312,
2773089,
41684313,
32123776,
32119880,
41678357,
41678554,
2777007,
9884,
9738
)
如果有必要,-saveGame将从导航控制器中的UIBarButton调用
感谢您的帮助。这是错误的:
- (id)initWithCoder:(NSCoder *)coder {
self = [[Piece alloc] init];
if (self != nil)
{
当调用initWithCoder:
时,已经分配了类的实例。在代码中,您正在泄漏该实例。您应该这样做:
- (id)initWithCoder:(NSCoder *)coder {
self = [super init]; // or [self init] if needed
if (self != nil)
{
另外,当你解码一个对象时,你并不拥有它,所以你需要保留它
board = [[coder decodeObjectForKey:@"board"] retain];
如果你没有“获得”保留/释放规则,现在就学习它们,否则你会不断地攻击自己的脚
另外,您的saveGame
方法也存在一些问题
savedGames
为nil,则将对象而不是数组保存到文件中。这意味着在下一次运行时,未归档对象将不会像您期望的那样成为数组NSMutableArray
并不重要,如果存档一个可变数组,则在unarchive上会得到一个不可变数组。如果要修改未归档的数组,需要调用mutableCopy
我不确定是否存在异常,但请修复上述问题,否则它将消失,或者解决方案将变得更容易找到。如果您的NSKeyedArchiver无法正常工作,可能另一个选项是WriteFile:
- (NSString *) saveFilePath:(NSString*)fileName {
NSArray *saveFilePathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filePath = [[NSString alloc] initWithFormat:@"%@.extension", fileName];
return [[saveFilePathArray objectAtIndex:0] stringByAppendingPathComponent:filePath];
[saveFilePathArray release];
[filePath release];
}
...
NSMutableArray *yourUnsavedGameObject = [[NSMutableArray alloc] initWithArray:yourUnsavedGame];
// Write the dictionary to a file
[yourUnsavedGameObject writeToFile:[self saveFilePath] atomically:YES];
...
你忘记发帖了。代码有什么特别的问题吗?对不起,我用特别的问题编辑了我的原始帖子。非常感谢,这解决了错误!我肯定会更多地研究内存管理。