App 终止时如何使用 NSUserDefault 保存自定义对象数组?

发布于 2025-01-01 17:27:38 字数 2979 浏览 1 评论 0原文

因此,我尝试在应用程序终止时保存一个数组,以便在启动备份时可以重新填充该数组。不过,我遇到了很多不同的错误,主要是当我在应用程序启动时尝试重新创建数组时。我已采取步骤对自定义对象进行编码和解码,但也许我做得不正确...这是我的代码:

- (void)applicationWillTerminate:(UIApplication *)application
{
/*
 Called when the application is about to terminate.
 Save data if appropriate.
 See also applicationDidEnterBackground:.
 */

//Here is Where I save the array. "tasks is a pre-populated array of objects

NSData *taskData = [NSKeyedArchiver archivedDataWithRootObject:tasks];
[[NSUserDefaults standardUserDefaults]setObject:taskData forKey:@"tasks"];

}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

tasks = [[NSMutableArray alloc]init];

NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];

//NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];

if([[NSUserDefaults standardUserDefaults] objectForKey:@"tasks"]){

    NSData *tasksData = [[NSUserDefaults standardUserDefaults]objectForKey:@"tasks"];

 //It usually breaks right here

 tasks = [NSKeyedUnarchiver unarchiveObjectWithData:tasksData];

}

这是“tasks”数组包含的“Task”对象:

Task.h

#import <Foundation/Foundation.h>

@class TeamMember;
@class Project;


@interface Task : NSObject<NSCoding>{

NSDate *endDate;
NSDate *startDate;
NSMutableString* notes;
NSMutableString* taskName;
TeamMember *teamMember;
Project *project;
}
- (void)encodeWithCoder:(NSCoder *)encoder;
- (id)initWithCoder:(NSCoder *)decoder; 

@property  (nonatomic, retain)TeamMember *teamMember;
@property  (nonatomic, retain) Project * project;

@property (nonatomic, retain) NSMutableString *notes;
@property (nonatomic, retain) NSMutableString *taskName;
@property (nonatomic, retain) NSDate *startDate;
@property (nonatomic, retain) NSDate *endDate;


@end

Task。米

#import "Task.h"


@implementation Task
@synthesize notes;
@synthesize taskName;
@synthesize endDate;
@synthesize startDate;
@synthesize teamMember;
@synthesize project;


//@synthesize project;
- (void)encodeWithCoder:(NSCoder *)encoder {
//Encode properties, other class variables, etc
[encoder encodeObject:self.notes forKey:@"notes"];
[encoder encodeObject:self.taskName forKey:@"taskName"];
[encoder encodeObject:self.endDate forKey:@"endDate"];
[encoder encodeObject:self.startDate forKey:@"startDate"];

//you need to add in the encoding for teammember and project
}

- (id)initWithCoder:(NSCoder *)decoder {
if((self = [super init])) {
    //decode properties, other class vars
    self.notes = [decoder decodeObjectForKey:@"notes"];
    self.taskName = [decoder decodeObjectForKey:@"taskName"];
    self.endDate = [decoder decodeObjectForKey:@"endDate"];
    self.startDate = [decoder decodeObjectForKey:@"startDate"];

    //decode teamMember and Project here

}
}



@end

So I'm trying to save an array when the app terminates so that I can re-populate the array when I start back up. I'm running into a lot of different errors though, mostly when I try to recreate the array when the app launches. I have taken steps to encode and decode the custom objects, but maybe i'm not doing it correctly... Here is my code:

- (void)applicationWillTerminate:(UIApplication *)application
{
/*
 Called when the application is about to terminate.
 Save data if appropriate.
 See also applicationDidEnterBackground:.
 */

//Here is Where I save the array. "tasks is a pre-populated array of objects

NSData *taskData = [NSKeyedArchiver archivedDataWithRootObject:tasks];
[[NSUserDefaults standardUserDefaults]setObject:taskData forKey:@"tasks"];

}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

tasks = [[NSMutableArray alloc]init];

NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];

//NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];

if([[NSUserDefaults standardUserDefaults] objectForKey:@"tasks"]){

    NSData *tasksData = [[NSUserDefaults standardUserDefaults]objectForKey:@"tasks"];

 //It usually breaks right here

 tasks = [NSKeyedUnarchiver unarchiveObjectWithData:tasksData];

}

Here is the "Task" object that the "tasks" array contains:

Task.h

#import <Foundation/Foundation.h>

@class TeamMember;
@class Project;


@interface Task : NSObject<NSCoding>{

NSDate *endDate;
NSDate *startDate;
NSMutableString* notes;
NSMutableString* taskName;
TeamMember *teamMember;
Project *project;
}
- (void)encodeWithCoder:(NSCoder *)encoder;
- (id)initWithCoder:(NSCoder *)decoder; 

@property  (nonatomic, retain)TeamMember *teamMember;
@property  (nonatomic, retain) Project * project;

@property (nonatomic, retain) NSMutableString *notes;
@property (nonatomic, retain) NSMutableString *taskName;
@property (nonatomic, retain) NSDate *startDate;
@property (nonatomic, retain) NSDate *endDate;


@end

Task.m

#import "Task.h"


@implementation Task
@synthesize notes;
@synthesize taskName;
@synthesize endDate;
@synthesize startDate;
@synthesize teamMember;
@synthesize project;


//@synthesize project;
- (void)encodeWithCoder:(NSCoder *)encoder {
//Encode properties, other class variables, etc
[encoder encodeObject:self.notes forKey:@"notes"];
[encoder encodeObject:self.taskName forKey:@"taskName"];
[encoder encodeObject:self.endDate forKey:@"endDate"];
[encoder encodeObject:self.startDate forKey:@"startDate"];

//you need to add in the encoding for teammember and project
}

- (id)initWithCoder:(NSCoder *)decoder {
if((self = [super init])) {
    //decode properties, other class vars
    self.notes = [decoder decodeObjectForKey:@"notes"];
    self.taskName = [decoder decodeObjectForKey:@"taskName"];
    self.endDate = [decoder decodeObjectForKey:@"endDate"];
    self.startDate = [decoder decodeObjectForKey:@"startDate"];

    //decode teamMember and Project here

}
}



@end

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

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

发布评论

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

评论(1

泅渡 2025-01-08 17:27:38

忽略将这样的数组保存到 NSUserDefaults 而不是使用 CoreData 的事实是糟糕的设计,您的问题是您没有同步默认值。在 applicationWillTerminate 方法的底部添加此行 [[NSUserDefaults standardUserDefaults] Synchronize];

请使用 CoreData。用户默认值并不是用于数据持久性,它们旨在存储一些小数据块,例如布尔值或需要恢复的某些特定区域的宽度和高度,而不是实际上需要恢复的自定义用户内容坚持下来了。

另外,不要使用 applicationWillTerminate 方法作为保存数据的手段,应在用户添加数据后立即保存。此方法不保证其内容执行将正确完成。

Disregarding the fact that saving such an array to NSUserDefaults instead of using CoreData is poor design, your problem is that you're not synchronizing the defaults. Add this line [[NSUserDefaults standardUserDefaults] synchronize]; at the bottom of applicationWillTerminate method.

And please, use CoreData. User defaults aren't purposed for data persistence, they're designed to store a few small chunks of data, like bools, or widths and heights of some specific areas which needs to be restored, not custom user content, that actually needs to be persisted.

Also, do not use applicationWillTerminate method as your resort to saving data, save it right after user adds it. This method does not guarantee that its contents execution will be finished properly.

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