Какао NSBrowser и CFURLEnumeratorCreateDirectoryURL - PullRequest
0 голосов
/ 28 марта 2012

Я пытаюсь понять пример от Apple "ComplexBrowser", но действительно трудно найти какой-либо материал / учебник для "CFURLEnumeratorCreateDirectoryURL".

Образец ComplexBrowser от Apple

Что именно происходит в этом фрагменте кода?

Я не понял этот способ зацикливания с помощью CFURLEnumeratorGetNextURL и прочего.

Для меня подход с NSFileManager кажется более простым, но более ограниченным?

NSArray * contentsAtPath = [[NSFileManager defaultManager] contentsOfDirectoryAtPath: ошибка parentPath: 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;

}

1 Ответ

1 голос
/ 28 марта 2012

Поскольку эта информация хранится в непрозрачном типе данных C, в базовом фундаменте они предоставляют подпрограммы C, которые предоставляют вам информацию о данных.Это форма инкапсуляции, так что они могут изменить ситуацию за кулисами и не повлиять на открытый интерфейс библиотеки.

По сути, они создают цикл и продолжают запрашивать следующий URL из каталога, пока не найдутконец каталога.

  • enumerator является своего рода индексом, который отслеживает, где они находятся в списке URL.
  • enumeratorResult говорит нам, действительно ли этомы получили новый URL (или произошла ошибка, или мы находимся в последней записи).

Когда он проходит через каждый URL, он создает FileSystemNode и добавляет их в массив, а затем возвращает массив, когда завершает цикл по всем URL-адресам в каталоге.

...