Loading data should be "lazy". This means the data should be loaded the first instant that you actually need to read the data. Also, if it's a lot of data, you should be prepared to free it while your app is running so other apps can use the RAM, this means your app is more likely to still be running next time the user launches your app.
So, make a class that provides access to the data, and the first time anything needs data it checks if the internal NSCoding
object is nil
, and if it is then that is where you should load the data.
As for saving, you should save before terminating but more importantly you should also save within a second or so of any data being modified by the user. Your app should crash at any moment due to a software bug, or it could be terminated for some other reason, or the battery could simply run out.
Lets say your internal data storage is an NSMutableDictionary
saved using NSKeyedArchiver
. It has a value with the key @"value"
, with a "getter" and "setter" implemented like this:
- (NSString *)value
{
if (!self.data)
self.data = [NSKeyedUnarchiver unarchiveObjectWithFile:self.dataFile];
return self.data[@"value"];
}
- (void)setValue:(NSString *)value
{
if (!self.data)
self.data = [NSKeyedUnarchiver unarchiveObjectWithFile:self.dataFile];
self.data[@"value"] = value;
self.needsSave = YES;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self save];
});
}
- (void)save
{
if (!self.needsSave)
return;
[NSKeyedArchiver archiveRootObject:self.data toFile:self.dataFile];
self.needsSave = NO;
}
Finally, your class should also register for UIApplicationDidReceiveMemoryWarningNotification
, UIApplicationWillResignActiveNotification
, UIApplicationWillTerminateNotification
, where you want to save to disk and free the RAM so other apps can use it:
- (id)init
{
if (!(self = [super init]))
return nil;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveAndFreeMemory:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveAndFreeMemory:) name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveAndFreeMemory:) name:UIApplicationWillTerminateNotification object:nil];
return self;
}
- (void)saveAndFreeMemory:(NSNotification *)notif
{
[self save];
self.data = nil;
}