iPhone – 归档自定义对象数组
我已经尝试了几个小时,我无法解决这个问题.
我正在制作一个可以保存未完成的国际象棋游戏的应用程序,所以我正在尝试将数组写入文件. 如果有意义的话,这就是数组: -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,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; } Piece.m - (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的这一行之后会出现错误: 这就是控制台中显示的内容: 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,564412,342037,606848,17686,2733061,4646817,3140430,3149167,3144379,2837983,2746312,2773089,41684313,32123776,32119880,41678357,41678554,2777007,9884,9738 ) 如果重要,则从导航控制器中的UIBarButton调用-saveGame. 任何帮助表示赞赏,谢谢. 解决方法
这是错的:
- (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,则表示您将对象而非数组保存到文件中.这意味着在下次运行时,未归档的对象将不是您期望的数组. 我完全不确定异常,但是修复了上述问题,要么它会消失,要么解决方案会变得更容易找到. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |