I'm having trouble figuring out why NSUserDefaults
is leaving junk plist files in Library/Preferences for my app.
I'm seeing the following files...
com.mycompany.myapp.plist
com.mycompany.myapp.plist.3gaPYul
com.mycompany.myapp.plist.c97yxEH
... etc. The plist.*
files are 0 bytes. It seems that everytime the app is run, it leaves a new one behind. I made sure I'm not calling -[NSUserDefaults synchronize]
at all, however if I do call it, it hastens the junk files appearance for a given run. Stepping through in a debugger, as soon as i step over the call to synchronize, a new file has appeared. If I take out the synchronize call, a new junk file appears sometimes on app start, other times on app quit.
I'm also checking to see if maybe I'm setting a user default on a thread (unlikely, but a possibility perhaps), thought the docs say it is thread safe.
Any help is appreciated. Thanks!
EDIT:
Just found this: CFPreferences creates multiple files
While I agree with the answerers idea, it doesn't explain the "Why?" part.
I've become convinced this is an Apple bug, but i've been unable to craft a small sample illustrating it. I've gotten a ton of feedback saying Apple's own apps do this. Since i've kind of hit a wall and need to keep moving, i've ended up doing a nasty hack shown below.
@implementation NSUserDefaults(Hack)
- (BOOL)synchronize
{
BOOL result = CFPreferencesAppSynchronize((CFStringRef)[[NSBundle mainBundle] bundleIdentifier]);
if (!result)
{
// there's probably a temp file lingering around... try again.
result = CFPreferencesAppSynchronize((CFStringRef)[[NSBundle mainBundle] bundleIdentifier]);
// regardless of the result, lets clean up any temp files hanging around..
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *prefsDir = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Preferences"];
NSDirectoryEnumerator *dirEnumerator = [fileManager enumeratorAtPath:prefsDir];
NSString *file = nil;
NSString *match = [[[NSBundle mainBundle] bundleIdentifier] stringByAppendingString:@".plist."];
while ((file = [dirEnumerator nextObject]))
{
if ([file rangeOfString:match].location != NSNotFound)
{
NSString *fileToRemove = [prefsDir stringByAppendingPathComponent:file];
[fileManager removeItemAtPath:fileToRemove error:nil];
}
}
}
return result;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With