Нужна помощь для быстрого поиска значения в списке свойств iOS (plist)?

#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:), чтобы найти пересечение.