【问题标题】:Sorting an array of NSURL objects by creation date按创建日期对 NSURL 对象数组进行排序
【发布时间】:2012-01-03 22:59:01
【问题描述】:

我将图像缓存到一个目录 (/Library/Caches/ImageCache/)。当目录超过一定大小时,我想删除目录中最旧的文件。为了完成这个任务,我使用 NSFileManager 来检索目录内容。然后我尝试按日期对该数组进行排序并删除最旧的对象。

我的问题是,当我尝试通过键 NSURLCreationDateKey 对数组进行排序时,我的程序崩溃了。

NSFileManager *defaultFM = [NSFileManager defaultManager];
NSArray *keys = [NSArray arrayWithObjects:NSURLNameKey, NSURLCreationDateKey, nil];
NSURL *cacheDirectory = [self photoCacheDirectory];  // method that returns cache URL
NSArray *cacheContents = [defaultFM contentsOfDirectoryAtURL:cacheDirectory
                                  includingPropertiesForKeys:keys
                                                     options:NSDirectoryEnumerationSkipsSubdirectoryDescendants
                                                       error:nil];

NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:NSURLCreationDateKey ascending:YES];
NSArray *sortedArray = [cacheContents sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];

程序在最后一行崩溃。有错误:

* 由于未捕获的异常“NSUnknownKeyException”而终止应用程序,原因:“[valueForUndefinedKey:]:此类与键 NSURLCreationDateKey 的键值编码不兼容。”

【问题讨论】:

    标签: iphone objective-c ios ios5


    【解决方案1】:

    编辑:更好的答案

    如果这不起作用,您将不得不编写自己的比较器块并手动获取日期以进行比较:(

    [cacheContents sortUsingComparator:^ (NSURL *a, NSURL *b) {
        // get the two dates
        id da = [[a resourceValuesForKeys:[NSArray arrayWithObject:NSURLCreationDateKey] error:nil] objectForKey:NSURLCreationDateKey];
        id db = [[b resourceValuesForKeys:[NSArray arrayWithObject:NSURLCreationDateKey] error:nil] objectForKey:NSURLCreationDateKey];
    
        // compare them
        return [da compare:db];
    }];
    

    (同样的免责声明仍然适用,但我什至不确定它是否会编译;) - 不过你明白了!)


    这是我的第一个答案(包含在此处以供后代使用,但主要只是说明正确阅读问题的重要性:)

    这是因为你得到了一个NSURL 对象的数组;这些没有NSURLCreationDateKey 属性。

    试试这个(免责声明 - 不是 100% 会起作用)

    NSString *key = [NSString stringWithFormat:@"fileAttributes.%@", NSURLCreationDateKey];
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:key ascending:YES];
    

    您的排序依据是 fileAttributes 字典的一个属性,而该字典又是您的枚举器的一个属性。

    【讨论】:

    • 感谢院长的建议。不过,我仍然遇到同样的错误。
    • 如果不应该完全一样,它应该说this class is not key value coding-compliant for the key fileAttributes.NSURLCreationDateKey.' - 无论如何,请参阅我的编辑以获取另一个解决方案:)
    • 好吧,我是个白痴——我一直假设你在使用枚举器,但看看你的问题,你显然不是。我是个白痴!查看我对比较器块的编辑编辑,它应该可以帮助你做你想做的事!
    • 罗恩,谢谢!那行得通。我还愚蠢地意识到,由于我的程序将文件添加到目录中以便查看它们,因此返回数组开头的那些 cacheContents 总是最新的!...我不确定这是否假设总是安全的,所以比较器是一种更好的方法。感谢您的帮助和耐心!
    • 我总是直言不讳;如果我想按顺序显示某些东西,我会对其进行排序(除非文档明确说明它将按该顺序排列!)。你永远不知道这是否只是巧合,或者它是否会在更高版本的 iOS 等中发生变化 :)
    【解决方案2】:

    我对此并不肯定,但我认为 contentsOfDirectoryAtURL: 方法返回一个不是 KVC 对象的 URL 列表。要从 NSURL 获取你想要的属性,你需要调用:

    getResourceValue:forKey:error:

    由于这与 KVC 不兼容,您将无法使用排序描述符,而需要使用 [cacheContents sortedArrayUsingComparator:...] 之类的例程

    【讨论】:

    • 嗨,罗恩,你是对的。 Contents 返回一个 NSURL 对象数组,我可以通过以下方式单独访问这些对象的键: NSURL *url = [cachedContents objectAtIndex:0]; NSDictionary *values = [url resourceValuesForKeys:keys error:nil];使用比较器是否必须在我的类中实现另一种方法来比较 NSURL 对象给出的两个日期?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-02
    • 1970-01-01
    • 2016-11-05
    • 2011-10-30
    • 2015-02-25
    相关资源
    最近更新 更多