#objective-c #ios #plist #nsdictionary
#objective-c #iOS #plist #nsdictionary
Вопрос:
В настоящее время в моем проекте iOS есть файл plist, который загружается из Интернета при появлении обновлений, и он содержит список новостных статей вместе с изображениями.
Приложение кэширует изображения на iPhone для автономного доступа, в настоящее время я пытаюсь написать функцию, которая будет время от времени очищать кэшированные файлы.
В настоящее время у меня есть этот код, который ищет изображения во временной папке, а затем удаляет их, однако для каждого найденного изображения я бы хотел, чтобы он проверял, существует ли имя файла в виде значения в списке, хранящемся как NSDictionary, перед удалением, однако я не уверен в быстром способе поиска NSDictionary безнеобходимость в операторе for .
Любые советы были бы замечательными.
NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:TMP error:nil];
if (files == nil) {
// error...
NSLog(@"no files found");
}
for (NSString *file in files) {
NSString *uniquePath = [TMP stringByAppendingPathComponent: file];
if([file rangeOfString: @".png" options: NSCaseInsensitiveSearch].location != NSNotFound)
{
NSLog(@"%@", file);
if ([[NSFileManager defaultManager] removeItemAtPath: uniquePath error: NULL] == YES)
NSLog (@"Remove successful");
else
NSLog (@"Remove failed");
}
}
Редактировать
В настоящее время я добавил это, не уверен, что это лучший способ сделать это, но он работает.
NSArray *newsArray = [self.newsData allValues];
// Convert the Array into a string
NSString *newsString = [newsArray description];
// Perform Range Search.
NSRange range;
range = [newsString rangeOfString : filename];
if (range.location != NSNotFound) {
NSLog(@"The file exists in the plist %@", filename);
} else {
// Delete the file
}
Ответ №1:
Вы можете уменьшить массив так, чтобы он содержал только интересующие вас объекты, используя a NSPredicate
, а затем быстро перебирать объекты, которые вы хотите удалить. Вот так:
NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:TMP error:nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[cd] '.png'"];
NSArray *filteredArray = [files filteredArrayUsingPredicate:thePredicate];
for (NSString *file in filteredArray) {
NSString *uniquePath = [TMP stringByAppendingPathComponent:file];
if ([[NSFileManager defaultManager] removeItemAtPath: uniquePath error: NULL])
NSLog (@"Remove successful");
else
NSLog (@"Remove failed");
}
Это будет означать, что цикл for выполняет цикл только по интересующим вас объектам.
Комментарии:
1. Спасибо за это, я на самом деле хочу выполнить обратный поиск, т.Е. перебрать файлы изображений на устройстве, а затем посмотреть, существует ли это имя файла в моем списке, поскольку список будет заменяться при каждом запуске новой версией с веб-сайта.
2. Я вижу, значит, вы фильтруете .png, чтобы просто определить, что файл является файлом изображения, и вам все еще нужна логика для проверки списка?
3. Я в основном получаю список каталогов папки, затем для каждого файла физического изображения (png), найденного на диске, мне нужно проверить, существует ли его имя файла в файле plist
4. Я вижу, вам просто нужно создать предикат для каждой итерации цикла, а затем запустить его в массиве словарей, возвращаемых из списка, метод predicate evaluateWithObject сообщит вам, находится ли он внутри списка или нет, я сейчас ухожу, но обновлю свой ответ, когда вернусь
Ответ №2:
Поскольку вас не волнует последовательность файлов в списке или папке, и у вас, очевидно, не будет дублирования, используйте NSSet, а не NSArray, а затем используйте метод intersect (intersectsSet:), чтобы найти пересечение.