如何在 iOS 中保存一个充满自定义类的数组?
在我为学校项目创建的 iOS 应用程序中,我在保存存储在 NSMutableArray 中的数据时遇到问题。该数组是在应用程序委托文件中创建的,然后在各种其他视图控制器文件中创建它的委托。数组中存储的数据由自定义类组成,这些自定义类由 NSStrings 和 NSNumbers 作为属性组成。
我已经阅读并遵循了该网站上的许多示例大约一周了,但我一生都无法弄清楚。我还研究了核心数据,但在不完全重新开始的情况下我无法弄清楚如何实现它,不幸的是我时间紧迫。
我尝试过的事情:
在 WillTerminate 方法中存档。 (activityArray 是我的数组)
- (void)applicationWillTerminate:(UIApplication *)application {
NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString* arrayFile = [documentsPath stringByAppendingPathComponent:@"arrayFile"];
[NSKeyedArchiver archiveRootObject:activityArray toFile:arrayFile];
[activityArray release];
然后在 AppDelegate 文件的 didFinishLaunchingWithOptions 方法中取消存档
NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *arrayFile = [documentsPath stringByAppendingPathComponent:@"arrayFile"];
if ([fileManager fileExistsAtPath:arrayFile]) {
NSLog(@"yes");
activityArray = [NSMutableArray arrayWithContentsOfFile:arrayFile];
} else {
activityArray = [[NSMutableArray alloc] init];
}
根据其他问题的建议,我在自定义类中执行了以下操作(这类有 2 个 NSString,activityName 和 ActivityDescription)。
- initWithCoder:(NSCoder *)aCoder {
self = [super init];
activityName = [[aCoder decodeObjectForKey:@"activityName"] retain];
activityDescription = [[aCoder decodeObjectForKey:@"activityDescription"] retain];
return self;
}
-(void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:activityName forKey:@"activityName"];
[aCoder encodeObject:activityDescription forKey:@"activityDescription"];
}
但这些似乎都不适合我。任何帮助将不胜感激。我觉得这应该是一件相当容易的事情,但我似乎无法理解。
In an iOS application I am creating for a school project, I am having trouble saving data that is stored in an NSMutableArray. The array is created in the app delegate file, and then delegates for it are created in various other view controller files. The data stored in the array consists of custom classes made up of NSStrings and NSNumbers as properties.
I've read and followed many examples on this site for about a week now, but I can't for the life of me figure it out. I've also looked into core data, but I couldn't figure out how to implement that without completely starting over, and I'm pressed for time unfortunately.
Things I have tried:
Archiving in the WillTerminate method. (activityArray is my array)
- (void)applicationWillTerminate:(UIApplication *)application {
NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString* arrayFile = [documentsPath stringByAppendingPathComponent:@"arrayFile"];
[NSKeyedArchiver archiveRootObject:activityArray toFile:arrayFile];
[activityArray release];
And then unarchiving in the didFinishLaunchingWithOptions method of the AppDelegate file
NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *arrayFile = [documentsPath stringByAppendingPathComponent:@"arrayFile"];
if ([fileManager fileExistsAtPath:arrayFile]) {
NSLog(@"yes");
activityArray = [NSMutableArray arrayWithContentsOfFile:arrayFile];
} else {
activityArray = [[NSMutableArray alloc] init];
}
As per suggestions on other questions, I did the following in the custom classes I have (this class has 2 NSStrings, activityName and activityDescription).
- initWithCoder:(NSCoder *)aCoder {
self = [super init];
activityName = [[aCoder decodeObjectForKey:@"activityName"] retain];
activityDescription = [[aCoder decodeObjectForKey:@"activityDescription"] retain];
return self;
}
-(void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:activityName forKey:@"activityName"];
[aCoder encodeObject:activityDescription forKey:@"activityDescription"];
}
But none of this seems to work for me. Any help is gratefully appreciated. I feel like this should be a rather easy thing, but I just can't seem to get it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Core Data 实际上实现起来非常简单且快速。几个月前,我发表了一篇关于快速设置的博客文章。只需创建实体来表示您创建的不同类或自己添加 @dynamic 属性。
请记住,核心数据的行为与数组相同,因为只能存储对象。因此,您需要将 NSNumber 用于 int\floats 等。
Core Data is actually very simple and fast to implement. I made a blog post on quickly getting it setup a few months ago. Simply make entities to represent the different classes you have created or add the @dynamic properties yourself.
Keep in mind that Core Data behaves the same as an Array in that only objects can be stored. Thus you need to use NSNumber for int\floats, etc.
您可以使用 NSUserDefaults 保存数组,如下所示:
然后您可以按如下方式检索保存对象:
但是,要使其工作,您必须为您提到的涉及的任何自定义对象实现 initWithCoder 和encodeWithCoder 方法。
You can save your array using the NSUserDefaults like this:
Then you can retrieve the save object as following:
However for this to work, you must implement the initWithCoder and encodeWithCoder methods for any custom objects involved as you have mentioned.
您是否真正检查过您的归档代码是否已执行?在启用多任务处理的 iOS 4 下,几乎不会调用
applicationWillTerminate:
。您应该考虑将代码放入applicationDidEnterBackground:
中。至于归档后释放数组,当用户离开应用程序(它将被挂起)并稍后返回(应用程序只是重新激活,而不是重新启动)时,这将失败。在这种情况下,您释放数组的事实将导致您的应用程序崩溃。
Have you actually checked if your archiving code is executed at all? Under iOS 4 w/ multitasking enabled,
applicationWillTerminate:
is practically never called. You should consider putting the code inapplicationDidEnterBackground:
instead.As for releasing the array after archiving, that would fail when the user leaves the app (it will be suspended) and later comes back (the app is just reactivated, not restarted). In that case, the fact that you released the array will cause your app to crash.