iPhone – 归档自定义对象数组

前端之家收集整理的这篇文章主要介绍了iPhone – 归档自定义对象数组前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经尝试了几个小时,我无法解决这个问题.

我正在制作一个可以保存未完成的国际象棋游戏的应用程序,所以我正在尝试将数组写入文件.

如果有意义的话,这就是数组:

  1. -NSMutableArray savedGames
  2. --GameSave a
  3. ---NSMutableArray board;
  4. ----Piece a,b,c,etc.
  5. -----some ints
  6. ---NSString whitePlayer,blackPlayer;
  7. ---int playerOnTop,turn;
  8. --GameSave b
  9. ---NSMutableArray board;
  10. ----Piece a,turn;

等等

这些是我的NSCoding方法

GameSave.m

  1. - (void)encodeWithCoder:(NSCoder *)coder {
  2. [coder encodeObject:whitePlayer forKey:@"whitePlayer"];
  3. [coder encodeObject:blackPlayer forKey:@"blackPlayer"];
  4. [coder encodeInt:playerOnTop forKey:@"playerOnTop"];
  5. [coder encodeInt:turn forKey:@"turn"];
  6. [coder encodeObject:board forKey:@"board"];
  7. }
  8.  
  9. - (id)initWithCoder:(NSCoder *)coder {
  10. self = [[GameSave alloc] init];
  11. if (self != nil)
  12. {
  13. board = [coder decodeObjectForKey:@"board"];
  14. whitePlayer = [coder decodeObjectForKey:@"whitePlayer"];
  15. blackPlayer = [coder decodeObjectForKey:@"blackPlayer"];
  16. playerOnTop = [coder decodeIntForKey:@"playerOnTop"];
  17. turn = [coder decodeIntForKey:@"turn"];
  18. }
  19. return self;
  20. }

Piece.m

  1. - (void)encodeWithCoder:(NSCoder *)coder {
  2. [coder encodeInt:color forKey:@"color"];
  3. [coder encodeInt:piece forKey:@"piece"];
  4. [coder encodeInt:row forKey:@"row"];
  5. [coder encodeInt:column forKey:@"column"];
  6. }
  7.  
  8. - (id)initWithCoder:(NSCoder *)coder {
  9. self = [[Piece alloc] init];
  10. if (self != nil)
  11. {
  12. color = [coder decodeIntForKey:@"color"];
  13. piece = [coder decodeIntForKey:@"piece"];
  14. row = [coder decodeIntForKey:@"row"];
  15. column = [coder decodeIntForKey:@"column"];
  16. }
  17. return self;
  18. }

这是试图存档并保存到文件代码

  1. - (void)saveGame {
  2. ChessSaverAppDelegate *delegate = (ChessSaverAppDelegate *) [[UIApplication sharedApplication] delegate];
  3. [[delegate gameSave] setBoard:board];
  4.  
  5. NSMutableArray *savedGames = [NSKeyedUnarchiver unarchiveObjectWithFile:[self dataFilePath]];
  6. if (savedGames == nil) {
  7. [NSKeyedArchiver archiveRootObject:[delegate gameSave] toFile:[self dataFilePath]];
  8. } else {
  9. [savedGames addObject:[delegate gameSave]];
  10. [NSKeyedArchiver archiveRootObject:savedGames toFile:[self dataFilePath]];
  11. }
  12. }
  13.  
  14. - (NSString *)dataFilePath {
  15. NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
  16. NSString *documentsDirectory = [paths objectAtIndex:0];
  17. return [documentsDirectory stringByAppendingPathComponent:@"gameSaves.plist"];
  18. }

对不起,这是问题所在:

设置一些断点后,在-saveGame的这一行之后会出现错误
    [NSKeyedArchiver archiveRootObject:savedGames toFile:[self dataFilePath]];

这就是控制台中显示内容

  1. 2010-05-11 17:04:08.852 ChessSaver[62065:207] *** -[NSCFType encodeWithCoder:]: unrecognized selector sent to instance 0x3d3cd30
  2. 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'
  3. 2010-05-11 17:04:08.908 ChessSaver[62065:207] Stack: (
  4. 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
  5. )

如果重要,则从导航控制器中的UIBarButton调用-saveGame.

任何帮助表示赞赏,谢谢.

解决方法

这是错的:

  1. - (id)initWithCoder:(NSCoder *)coder {
  2. self = [[Piece alloc] init];
  3. if (self != nil)
  4. {

当initWithCoder:被调用时,已经分配了类的实例.在您的代码中,您正在泄漏该实例.你应该这样做:

  1. - (id)initWithCoder:(NSCoder *)coder {
  2. self = [super init]; // or [self init] if needed
  3. if (self != nil)
  4. {

此外,当您解码对象时,您不拥有它,因此您需要保留它.

  1. board = [[coder decodeObjectForKey:@"board"] retain];

如果你没有“获得”保留/释放规则,现在就学习它们,否则你将不断地用脚射击.

此外,您的saveGame方法有几个问题.

>如果savedGames为nil,则表示您将对象而非数组保存到文件中.这意味着在下次运行时,未归档的对象将不是您期望的数组.
>未归档的数组是不可变的.将类型声明为NSMutableArray并不重要,如果归档可变数组,则将在unarchive上获得不可变数组.如果要修改它,则需要在unarchived数组上调用mutableCopy.

我完全不确定异常,但是修复了上述问题,要么它会消失,要么解决方案会变得更容易找到.

猜你在找的Xcode相关文章