Detecting changed user defaults
I have an iPhone app and have implemented local notifications. The app has a page in Settings that allows a user to schedule notifications a specified number of days in advance of an event. To make sure that changes to the settings take effect every time a user activates the app, I have the following in my app delegate:
- (void)applicationDidBecomeActive:(UIApplication *)application {
[[NSUserDefaults standardUserDefaults] synchronize];
[self rescheduleAllNotificationsWithUserNotification:NO];
}
The problem is that the call to rescheduleAllNotificationsWithUserNotification:
takes a few seconds and the app feels a little sluggish on start.
I only need to call rescheduleAllNotificationsWithUserNotification:
if any of the settings have been changed. Is there a way to detect if the us开发者_运维百科er has changed any of the settings between app activations so I can avoid always rescheduling the notifications?
I think you might be looking for the NSUserDefaultsDidChangeNotification
notification.
You can register to listen to this notification and be informed whenever the user's preferences change.
You should use a way to put this method call in another thread is possible. performSelectorInBackground is an easy way to do it:
[self performSelectorInBackground:@selector(rescheduleAllNotificationsWithUserNotification:) withObject:NO];
That should help you get rid of the laggy performance. You could even use ^blocks, as you seem to be on iOS 4.
What I have done in the past, if there are not too many preference values to monitor, is to have alternate versions, sort of "the last time I ran" versions. One set of values is accessible through the Settings application but the other is only set from within the application.
NSString *name = (NSString *) CFPreferencesCopyAppValue( (CFStringRef) @"name_preference", kCFPreferencesCurrentApplication );
NSString *nameLastTime = (NSString *) CFPreferencesCopyAppValue( (CFStringRef) @"name_last_execution", kCFPreferencesCurrentApplication );
// Need obvious checks for empty or missing entries, etc., etc.
if( ![nameLastTime isEqual: name] ) {
// Store the new name as the name at last execution...
CFPreferencesSetAppValue( (CFStringRef) @"name_last_execution", (CFStringRef) name, kCFPreferencesCurrentApplication );
CFPreferencesAppSynchronize( kCFPreferencesCurrentApplication );
[self rescheduleAllNotificationsWithUserNotification:NO];
}
It is not real elegant with fancy object-oriented call-back methods, etc., but it gets the job done cheaply and reliably.
精彩评论