如何使用 NSKeyedArchiver 保存数据?

发布于 2024-10-09 16:00:40 字数 2732 浏览 8 评论 0原文

嗨,我正在尝试从我创建的类中保存一个对象。它称为 shot,包含 5 个我希望保存的变量。这是 .h 文件 --- 它切断了 NSCoding 和 NSMutableCopying 协议以及我的导入,但它们就在那里。

#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];
 }
}

我已将保存和加载方法设置为按钮,但我的数据仍然无法保存。请帮忙!!!

Hi, I am trying to save an object from a class I have created. It is called shot and Contains 5 variables I wish to save. Here is the .h file--- It cut off NSCoding and NSMutableCopying Protocals and my imports, but they are there.

#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;
}

I can't seem to get my data to saved when I use these methods

-(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];
 }
}

I have set the save and load methods up to buttons, but my data still won't save. Please help!!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我纯我任性 2024-10-16 16:00:40

我终于解决了这个问题。除了上述帮助之外,.archive 不是一种文件类型。您无法保存 .archive,只能保存 .arch 或 .plist 这是我的主要问题。

I have finally solved the problem. Other than the above help, .archive isn't a file type. You can't save a .archive, you can only save a .arch or a .plist That was my main problem.

过气美图社 2024-10-16 16:00:40

首先,你像筛子一样泄漏内存。大量的alloc/init & mutableCopy,没有release。我建议阅读内存管理指南

接下来,您的方法名称不遵循 Cocoa 约定。这些:

-(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: 应该调用 super 的 initWithCoder:,而不是 init

First, you are leaking memory like a sieve. Lots of alloc/init & mutableCopy, no releases. I'd suggest reading the memory management guide.

Next, your method names are not following the Cocoa conventions. These:

-(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;

Should be something like:

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

Also, getPath should just be path. Methods prefixed with get are both very rare and have a very specific meaning.

This is also nonsense:

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

There is no need for either of the [[Shot alloc]init] calls (those are both leaks).

Finally, your encoding methods are implemented incorrectly. As the documentation states, you need to call super as appropriate.

Specifically, your encodeWithCoder: must invoke super's implementation of same and initWithCoder: should call super's initWithCoder:, not init.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文