2010-12-30 1 views
7

У меня возникли проблемы с выяснением причин, почему NSUserDefaults оставляет файлы мусора в библиотеке/Предпочтения для моего приложения.Почему NSUserDefaults оставляет временные файлы plist в Library/Preferences для моего приложения?

Я вижу следующие файлы ...

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

... и т.д. plist.* файлы 0 байт. Кажется, что каждый раз, когда приложение запускается, оно оставляет новый. Я убедился, что я вообще не звоню -[NSUserDefaults synchronize], однако, если я его вызываю, он ускоряет появление нежелательных файлов для данного запуска. Выйдя в отладчик, как только я перейду к вызову для синхронизации, появился новый файл. Если я вынимаю вызов синхронизации, в старте приложения иногда появляется новый файл нежелательной почты, а иногда - при закрытии приложения.

Я также проверяю, возможно ли, что я устанавливаю по умолчанию пользователя в потоке (маловероятно, но возможно возможно), подумал, что документы говорят, что это потокобезопасность.

Любая помощь приветствуется. Благодаря!

EDIT:

Просто нашел это: "Почему?" CFPreferences creates multiple files

Хотя я согласен с идеей отвечающими, это не объясняет часть.

+0

Это довольно сумасшедший; дайте мне знать, если вы когда-нибудь узнаете, почему! –

+0

У меня была одна и та же проблема: временные plists на самом деле заканчиваются заполнением iPad полностью (тысячи файлов размером ~ 4 Мб, заканчивающиеся на несколько Gb). Определенно выглядит как ошибка iOS. – quentinadam

ответ

3

Я убедился, что это ошибка Apple, но я не смог создать небольшой образец, иллюстрирующий это. Я получил массу отзывов о том, что 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

У меня была одна и та же проблема: временные плиты на самом деле заканчиваются заполнением iPad полностью (тысячи файлов размером ~ 4 Мб, заканчивающиеся на несколько Gb). Определенно ошибка iOS. – quentinadam

1

Сохраняются ли эти файлы plist между запусками приложений? У вас есть ошибки при сохранении предпочтений? У вашего официальных plist есть разрешения на запись?

Списки свойств могут быть записаны атомарно, что означает, что они сначала записываются во временный файл и, если во время операции записи нет ошибки, временный файл переименовывается в исходное имя файла. При нормальных обстоятельствах вы не должны видеть временные файлы.

+0

Файлы plist сохраняются между запусками. Я не вижу ошибок в хранении данных, и права на запись правильные. Я видел, как временные файлы приходят и уходят в другие приложения (казалось, что они исчезают). Я делал это много лет, и в первый раз я когда-либо видел это поведение, поэтому он заставил меня почесать мне голову. Спасибо за предложения, не думал проверять разрешения. – bsneed

1

Мысль - это данные, которые вы храните в письменном виде в правильно названный файл? Я думаю, ты подразумевал, что это так. Мне интересно, открыт ли правильно названный файл с правами на запись чем-то другим, кроме NSDefaults, и если это блокирует безопасную копию сохранения на фазе временного файла?

+0

Обычная стратегия отладки применяется, конечно же; скопируйте всю папку проекта и начните упрощать, слегка разрывая материал и смотрите, когда поведение прекращается. Получите это достаточно просто, и вы либо найдете свою ошибку, либо попросите хорошую демонстрационную программу для репортера ошибок Apple: -/ – Dad

+0

Данные превращают его в нужный файл.Я не вижу, что есть какой-либо код, явно открывающий этот файл в Gity, но я буду продолжать его искать. – bsneed

+0

Если у вашего приложения не работает обычный цикл запуска? (например, только модальный цикл цикла или что-то еще). Или хм, интересно, часто ли вы обновляете значения по умолчанию из нескольких потоков, и вы видите какое-то состояние гонки, в котором второго не происходит, потому что первый находится в середине происходящего (или что-то еще) ... Кажется, больше как ошибка os в этот момент, хотя ... – Dad