因此,当我的应用程序终止时,我尝试将自定义对象的 NSMutableArray(代表 Course Planner 应用程序的大学课程的“课程”)写入文件,然后将该数组从文件中读取到将使用的相关 ViewController应用程序启动时的数据。
以下是相关代码:
课程AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
coursesViewController = [[SampleHomeScreen alloc] initWithNibName:@"SampleHomeScreen" bundle:nil];
NSString *filePath = [self dataFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
[coursesViewController setCourses:[NSKeyedUnarchiver unarchiveObjectWithFile: filePath]];
}
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillTerminate:)name:UIApplicationWillTerminateNotification object:app];
[window addSubview:coursesViewController.view];
[window makeKeyAndVisible];
return YES;
}
- (NSString *)dataFilePath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"data.plist"];
NSLog(@"%@", path);
return path;
}
/**
applicationWillTerminate: saves changes in the application's managed object context before the application terminates.
*/
- (void)applicationWillTerminate:(UIApplication *)application {
NSLog(@"%@", [coursesViewController courses]);
[NSKeyedArchiver archiveRootObject:[coursesViewController courses] toFile:[self dataFilePath]];
}
课程.h:
@interface Course : NSObject <NSCoding> {
NSString *name; //e.g. ECS 189H
double grade, totalWeight; //course grade in %
NSMutableArray *list;
}
@property (nonatomic, retain) NSString *name;
@property (nonatomic) double grade, totalWeight;
@property (nonatomic, retain) NSMutableArray *list;
-(Course *)initWithName:(NSString *)courseName;
@end
课程.m:
@implementation Course
@synthesize name, grade, totalWeight, list;
-(Course *)initWithName:(NSString *)courseName {
name = [courseName retain];
grade = -1.0;
totalWeight = 0.0;
list = [[NSMutableArray alloc] init];
[super init];
return self;
}
-(Course *)initWithCoder:(NSCoder *)aDecoder {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.grade = [aDecoder decodeDoubleForKey:@"grade"];
self.totalWeight = [aDecoder decodeDoubleForKey:@"totalWeight"];
self.list = [aDecoder decodeObjectForKey:@"list"];
[super init];
return self;
}
- (void) encodeWithCoder: (NSCoder *)coder
{
[coder encodeObject:name forKey:@"name"];
[coder encodeDouble:grade forKey:@"grade"];
[coder encodeDouble:totalWeight forKey:@"totalWeight"];
[coder encodeObject:list forKey:@"list"];
}
-(void)dealloc {
[name release];
[list release];
[super dealloc];
}
@end
[coursesViewController courses] 是保存课程对象的 NSMutableArray。我知道它拥有有效数据这一事实。
所以问题是,1:只有当我从 xcode 运行应用程序时,应用程序才会保存到 data.plist(即在 xcode 中单击“编译并运行”)。2:它从 plist 加载数据,但保存的只是课程名称以及成绩和总权重的默认值(分别为 -1 和 0)。所以实际上它们被保存,就好像 initWithName 被首先调用它们一样。
这是我第一次真正深入研究一个相当高级的 iOS 应用程序,所以作为一个新手,我可能遗漏了一些重要信息。如果是这种情况,请告诉我,我会更新问题。
谢谢!-H T
ps 如果相关,我将 info.plist 中的 doNotRunInBackground 设置为 true。