0

我试图理解来自 Apple“ComplexBrowser”的示例,但很难找到“CFURLEnumeratorCreateDirectoryURL”的任何材料/教程。

来自 Apple 的 ComplexBrowser 示例

这段代码到底发生了什么?

我不明白这种循环使用 CFURLEnumeratorGetNextURL 之类的方法。

对我来说,使用 NSFileManager 的方法似乎更简单,但更有限?

NSArray *contentsAtPath = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:parentPath error:NULL];

- (NSArray *)children {
if (_children == nil || _childrenDirty) {
    // This logic keeps the same pointers around, if possible.
    NSMutableArray *newChildren = [NSMutableArray array];

    CFURLEnumeratorRef enumerator = CFURLEnumeratorCreateForDirectoryURL(NULL, (CFURLRef) _url, kCFURLEnumeratorSkipInvisibles, (CFArrayRef) [NSArray array]);
    NSURL *childURL = nil;
    CFURLEnumeratorResult enumeratorResult;
    do {
        enumeratorResult = CFURLEnumeratorGetNextURL(enumerator, (CFURLRef *) &childURL, NULL);
        if (enumeratorResult == kCFURLEnumeratorSuccess) {
            FileSystemNode *node = [[[FileSystemNode alloc] initWithURL:childURL] autorelease];
            if (_children != nil) {
                NSInteger oldIndex = [_children indexOfObject:childURL];
                if (oldIndex != NSNotFound) {
                    // Use the same pointer value, if possible
                    node = [_children objectAtIndex:oldIndex];
                }
            }
            [newChildren addObject:node];
        } else if (enumeratorResult == kCFURLEnumeratorError) {
            // A possible enhancement would be to present error-based items to the user.
        }
    } while (enumeratorResult != kCFURLEnumeratorEnd);

    [_children release];
    _childrenDirty = NO;
    // Now sort them
    _children = [[newChildren sortedArrayUsingComparator:^(id obj1, id obj2) {
        NSString *objName = [obj1 displayName];
        NSString *obj2Name = [obj2 displayName];
        NSComparisonResult result = [objName compare:obj2Name options:NSNumericSearch | NSCaseInsensitiveSearch | NSWidthInsensitiveSearch | NSForcedOrderingSearch range:NSMakeRange(0, [objName length]) locale:[NSLocale currentLocale]];
        return result;
    }] retain];
}

return _children;

}

4

1 回答 1

1

Since this information is stored in an opaque C data type, in core foundation they provide C routines which give you information about the data. This is a form of encapsulation so that they can change things behind the scenes and not effect the public interface for the library.

Basically, they create a loop and keep asking for the next URL from the directory until they find the end of the directory.

  • enumerator is kind of an index that keeps track of where they are in the list of URL's.
  • enumeratorResult tells us whether or not we got a new URL (or there is an error, or we are at the last record).

As it goes through each URL, it creates FileSystemNode's and adds them to an array, and then returns the array when it is done looping through all of the URL's in the directory.

于 2012-03-28T19:57:44.733 回答