我无法弄清楚为什么NSUserDefaults
会在我的应用的库/首选项中留下垃圾plist文件。
我看到以下文件......
com.mycompany.myapp.plist
com.mycompany.myapp.plist.3gaPYul
com.mycompany.myapp.plist.c97yxEH
......等plist.*
个文件是0个字节。似乎每次运行应用程序时,它都会留下一个新的。我确定我根本没有调用-[NSUserDefaults synchronize]
,但是如果我确实调用它,它会加速给定运行的垃圾文件外观。在调试器中单步执行,一旦我跳过同步调用,就会出现一个新文件。如果我取出同步调用,有时候应用程序启动时会出现一个新的垃圾文件,其他时候会在应用程序退出时出现。
我还在检查是否可能在线程上设置用户默认值(不太可能,但也许是可能的),认为文档说它是线程安全的。
感谢任何帮助。谢谢!
编辑:
刚刚发现:CFPreferences creates multiple files
虽然我同意回答者的想法,但它没有解释“为什么?”一部分。
答案 0 :(得分:3)
我已经确信这是一个Apple漏洞,但我一直无法制作一个小样本来说明它。我得到了大量反馈,称苹果公司自己的应用就是这么做的。因为我有点撞墙并且需要继续前进,所以我最终做了一个令人讨厌的黑客攻击。
@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;
}
答案 1 :(得分:1)
这些plist文件在应用程序启动之间是否仍然存在?存储首选项时是否有错误?您的官方 plist是否启用了写入权限?
属性列表可以原子方式写入,这意味着它们首先写入临时文件,如果在写入操作期间没有错误,则将临时文件重命名为原始文件名。在正常情况下,您不应该看到临时文件。
答案 2 :(得分:1)
思考 - 您存储的数据是否写入正确命名的文件?我想你暗示它是。我想知道正确命名的文件是否打开了除NSDefaults以外的其他东西的写入权限,并且是否阻止了临时文件阶段的安全保存副本?