如何使用 NSKeyedArchiver 保存数据?
嗨,我正在尝试从我创建的类中保存一个对象。它称为 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我终于解决了这个问题。除了上述帮助之外,.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.
首先,你像筛子一样泄漏内存。大量的
alloc/init
&mutableCopy
,没有release
。我建议阅读内存管理指南。接下来,您的方法名称不遵循 Cocoa 约定。这些:
应该类似于:
另外,
getPath
应该只是path
。以get
为前缀的方法非常罕见,并且具有非常特定的含义。这也是无稽之谈:
不需要任何一个
[[Shot alloc]init]
调用(这些都是泄漏)。最后,您的编码方法实施不正确。 正如文档所述,您需要根据需要调用
super
。具体来说,您的
encodeWithCoder:
必须调用 super 的相同实现,并且initWithCoder:
应该调用 super 的initWithCoder:
,而不是init
。First, you are leaking memory like a sieve. Lots of
alloc/init
&mutableCopy
, norelease
s. I'd suggest reading the memory management guide.Next, your method names are not following the Cocoa conventions. These:
Should be something like:
Also,
getPath
should just bepath
. Methods prefixed withget
are both very rare and have a very specific meaning.This is also nonsense:
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 andinitWithCoder:
should call super'sinitWithCoder:
, notinit
.