Как сохранить данные с помощью NSKeyedArchiver? - PullRequest
2 голосов
/ 02 января 2011

Привет, я пытаюсь сохранить объект из созданного мною класса. Он называется shot и содержит 5 переменных, которые я хочу сохранить. Вот файл .h --- Он отрезал NSCoding и NSMutableCopying Protocals и мой импорт, но они есть.

#import <Foundation/Foundation.h>


@interface Shot : UIButton <NSCoding, NSMutableCopying> {

 int x;
 int y;
 int location;
 int quarter;
 bool made;

 int miss;
 int make;
}

@property()int x;

@property()int y;

@property()int location;

@property()int quarter;

@property()bool made;

-(void)set_x:(int)my_x set_y:(int)my_y set_quarter:(int)my_quarter set_made:(bool)my_made set_location:(int)my_location;

-(void)set_miss_AND_set_make;

@end

**Here are the methods I made to save the data in my .m file---**

-(void)encodeWithCoder:(NSCoder *)aCoder {

 [aCoder encodeInt:x forKey:@"x"];
 [aCoder encodeInt:y forKey:@"y"];
 [aCoder encodeInt:location forKey:@"location"];
 [aCoder encodeInt:quarter forKey:@"quarter"];
 [aCoder encodeBool:made forKey:@"made"];
}

-(id)initWithCoder:(NSCoder *)aDecoder {

 if (self = [super init]) {
 x = [aDecoder decodeIntForKey:@"x"];
 y = [aDecoder decodeIntForKey:@"y"];
 location = [aDecoder decodeIntForKey:@"location"];
 quarter = [aDecoder decodeIntForKey:@"quarter"];
 made = [aDecoder decodeBoolForKey:@"made"];
 }
 return self;
}

-(id)mutableCopyWithZone:(NSZone *)zone {

 Shot *newShot = [[Shot allocWithZone:zone]init];
 [newShot set_x:x set_y:y set_quarter:quarter set_made:made set_location:location];
 return newShot;
}

Я не могу сохранить свои данные при использовании этих методов

-(NSString *)getPath {

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
 NSString *documentFolder = [paths objectAtIndex:0];
 NSFileManager *fm = [[NSFileManager alloc]init];
 if ([fm fileExistsAtPath:documentFolder] == NO) {
  [fm createDirectoryAtPath:documentFolder withIntermediateDirectories:YES attributes:nil error:nil];
 }
 return [documentFolder stringByAppendingFormat:@"iStatTrackInfo.archive"];
}

-(void)saveData {

 NSString *path = [self getPath];
 [NSKeyedArchiver archiveRootObject:shotArray toFile:path];
}

-(void)loadData {

 NSString *path = [self getPath];
 NSFileManager *fm = [[NSFileManager alloc]init];
 if ([fm fileExistsAtPath:path] == YES) {
  shotArray = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
  return;
 }

 NSEnumerator *enumOne = [shotArray objectEnumerator];
 Shot *shotObject = [[Shot alloc]init];
 while (shotObject = [enumOne nextObject]) {
  Shot *shotShot = [[Shot alloc]init];
  shotShot = [shotObject mutableCopy];
  shotShot.frame = CGRectMake(0, 0, 50, 50);
  shotShot.backgroundColor = [UIColor whiteColor];
  [self addSubview:shotShot];
 }
}

Я установил методы сохранения и загрузки на кнопки, но мои данные по-прежнему не сохраняются. Пожалуйста, помогите !!!

Ответы [ 2 ]

2 голосов
/ 15 апреля 2011

Я наконец-то решил проблему.Помимо приведенной выше справки .archive не является типом файла.Вы не можете сохранить .archive, вы можете сохранить только .arch или .plist Это была моя главная проблема.

1 голос
/ 02 января 2011

Во-первых, вы теряете память, как сито. Много alloc/init & mutableCopy, нет release с. Я бы предложил прочитать руководство по управлению памятью .

Далее, ваши имена методов не соответствуют соглашениям Какао. Это:

-(void)set_x:(int)my_x set_y:(int)my_y set_quarter:(int)my_quarter set_made:(bool)my_made set_location:(int)my_location;

-(void)set_miss_AND_set_make;

Должно быть что-то вроде:

-(void) resetMissAndMake; // or just missAndMake or activateMissAndMake
-(void) setX:(NSInteger)xValue y:(NSInteger)yValue quarter:(NSInteger)quarterValue location:(NSInteger)aLocation;

Кроме того, getPath должно быть просто path. Методы с префиксом get очень редки и имеют очень специфическое значение.

Это тоже ерунда:

 Shot *shotObject = [[Shot alloc]init];
 while (shotObject = [enumOne nextObject]) {
  Shot *shotShot = [[Shot alloc]init];
  shotShot = [shotObject mutableCopy];

Нет необходимости ни в одном из вызовов [[Shot alloc]init] (это оба утечки).

Наконец, ваши методы кодирования реализованы неправильно. Как указано в документации , вам необходимо позвонить super, если необходимо.

В частности, ваш encodeWithCoder: должен вызывать реализацию super того же самого, а initWithCoder: должен вызывать супер initWithCoder:, а не init.

...