简体   繁体   中英

Sorting an array of NSURL objects by creation date

My caches images to a directory (/Library/Caches/ImageCache/). When the directory exceeds a certain size I would like to delete the oldest file in the directory. To accomplish this task I use NSFileManager to retrieve the directory contents. I then try to sort this array by date and delete the oldest object.

My problem is that my program crashes when I try to sort the array by the key 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]];

The program crashes on the last line. With error:

* Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ valueForUndefinedKey:]: this class is not key value coding-compliant for the key NSURLCreationDateKey.'

EDIT : Better answer

If that doesn't work, you will have to write your own comparator block and get the dates to compare manually :(

[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];
}];

(Same disclaimer still applies but I'm not even sure that will compile ;) - you get the idea though!)


Here is my first answer (included here for posterity but mostly it just shows how important it is to read the question properly :)

It's because you're getting an array of NSURL objects; these don't have a NSURLCreationDateKey property.

Try this (disclaimer - not 100% it will work)

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

Your key to sort by is a property of the fileAttributes dictionary which is, in turn, a property of your enumerator.

I'm not positive about this, but I think that the contentsOfDirectoryAtURL: method returns a list of URLs which are not KVC objects. To get the property you want from the NSURL, you need to call:

getResourceValue:forKey:error:

Since this is not KVC compatible, you won't be able to use a sort descriptor, and instead need to use a routine like [cacheContents sortedArrayUsingComparator:...]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM