为什么 NSUserDefaults 在我的应用程序的库/首选项中留下临时 plist 文件?

发布于 2024-10-10 04:17:58 字数 700 浏览 0 评论 0原文

我无法弄清楚为什么 NSUserDefaults 在我的应用程序的库/首选项中留下垃圾 plist 文件。

我看到以下文件...

com.mycompany.myapp.plist
com.mycompany.myapp.plist.3gaPYul
com.mycompany.myapp.plist.c97yxEH

...等。 plist.* 文件是 0 字节。似乎每次运行该应用程序时,都会留下一个新的应用程序。我确保我根本没有调用 -[NSUserDefaults Synchronize] ,但是如果我确实调用它,它会加速给定运行的垃圾文件的出现。在调试器中单步执行,一旦我单步执行同步调用,就会出现一个新文件。如果我取消同步调用,有时会在应用程序启动时出现新的垃圾文件,有时在应用程序退出时出现。

我还在检查是否可能在线程上设置用户默认值(不太可能,但也许有可能),认为文档说它是线程安全的。

任何帮助表示赞赏。谢谢!

编辑:

刚刚发现这个: CFPreferences 创建多个文件

虽然我同意回答者的想法,但它并不不解释“为什么?”部分。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

怀中猫帐中妖 2024-10-17 04:17:58

我已经确信这是苹果的一个错误,但我无法制作一个小样本来说明它。我收到了大量反馈说苹果自己的应用程序可以做到这一点。由于我有点碰壁并且需要继续前进,所以我最终做了如下所示的令人讨厌的黑客攻击。

@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;
}

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;
}
仙女山的月亮 2024-10-17 04:17:58

这些 plist 文件在应用程序启动之间是否仍然存在?您在存储首选项时是否遇到错误?您的官方 plist 是否启用了写入权限?

属性列表可以原子写入,这意味着它们首先写入临时文件,如果写入操作期间没有错误,则临时文件将重命名为原始文件名。正常情况下,您不应该看到临时文件。

Do these plist files persist between application launches? Are you having errors when storing preferences? Does your official plist have write permissions enabled?

Property lists can be written atomically, which means that they are first written to a temporary file and, if there's no error during the write operation, the temporary file is renamed to the original file name. Under normal circumstances, you shouldn’t see the temporary files.

成熟的代价 2024-10-17 04:17:58

思考 - 您存储的数据是否被写入正确命名的文件中?我认为你暗示了这一点。我想知道正确命名的文件是否由 NSDefaults 以外的其他程序以写权限打开,以及这是否会阻止临时文件阶段的安全保存副本?

Thought - is the data you are storing being written into the properly named file? I think you implied that it is. I'm wondering if the properly named file is open with write permissions by something other than NSDefaults and if that's blocking the safe save copy from the temp file phase?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文