NSFileManager 和 NSDirectoryEnumerator 崩溃?

发布于 2024-10-20 21:00:26 字数 1361 浏览 1 评论 0原文

下面的代码在 walker = [fileManager enumeratorAtPath:directory]; 处崩溃。该代码在第一次调用 refresh 时执行正常,但在第二次(及后续)调用时崩溃。

关于我可能做错了什么有什么想法吗?

- (void)refresh
{
    NSString* directory = nil;
    NSFileManager* fileManager = nil;
    NSDirectoryEnumerator* walker = nil;

    if(files == nil)
        files = [[NSMutableArray alloc] init];
    else
        [files removeAllObjects];

    ASSERT(files != nil);
    if(files == nil) goto EARLY_EXIT;

    fileManager = [[NSFileManager alloc] init];
    ASSERT(fileManager != nil);
    if(fileManager == nil) goto EARLY_EXIT;

    directory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    ASSERT(directory != nil);
    if(directory == nil) goto EARLY_EXIT;

    ASSERT(directory != nil);
    walker = [fileManager enumeratorAtPath:directory];
    ASSERT(walker != nil);
    if(walker == nil) goto EARLY_EXIT;

    NSString* file;
    while((file = [walker nextObject]) != nil)
    {       
        BOOL isDirectory = YES;
        if([fileManager fileExistsAtPath:file isDirectory:&isDirectory] && !isDirectory)
            [files addObject:file];
    }

EARLY_EXIT:

    //if(walker != nil)
    //  [walker release];

    if(fileManager != nil)
        [fileManager release];

    //if(directory != nil)
    //  [directory release];
}

The code below crashes at walker = [fileManager enumeratorAtPath:directory];. The code executes OK on the first call to refresh, but crashes on the second (and subsequent) calls.

Any ideas on what I might be doing wrong?

- (void)refresh
{
    NSString* directory = nil;
    NSFileManager* fileManager = nil;
    NSDirectoryEnumerator* walker = nil;

    if(files == nil)
        files = [[NSMutableArray alloc] init];
    else
        [files removeAllObjects];

    ASSERT(files != nil);
    if(files == nil) goto EARLY_EXIT;

    fileManager = [[NSFileManager alloc] init];
    ASSERT(fileManager != nil);
    if(fileManager == nil) goto EARLY_EXIT;

    directory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    ASSERT(directory != nil);
    if(directory == nil) goto EARLY_EXIT;

    ASSERT(directory != nil);
    walker = [fileManager enumeratorAtPath:directory];
    ASSERT(walker != nil);
    if(walker == nil) goto EARLY_EXIT;

    NSString* file;
    while((file = [walker nextObject]) != nil)
    {       
        BOOL isDirectory = YES;
        if([fileManager fileExistsAtPath:file isDirectory:&isDirectory] && !isDirectory)
            [files addObject:file];
    }

EARLY_EXIT:

    //if(walker != nil)
    //  [walker release];

    if(fileManager != nil)
        [fileManager release];

    //if(directory != nil)
    //  [directory release];
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南七夏 2024-10-27 21:00:26

事实证明,在 iOS 和 10.5 及更高版本中,您不应该再使用 [NSFileManager defaultManager] 。我已经使用 Cocoa 近 15 年了,所以对这个很感兴趣。我将把它作为对其他人的警告 -- TechZen

尽管您在这段代码中犯下了许多违背良好编程实践的罪过,但您真正的问题在这里:

fileManager = [[NSFileManager alloc] init];

NSFileManger 是一个每个应用程序中的单例。您永远不会自己初始化它。获取单例的正确方法是:

fileManager=[NSFileManager defaultManager];

... 返回单例。然而,您通常不会为属性或变量而烦恼,只需这样使用它即可:

walker = [[NSFileManager defaultManager] enumeratorAtPath:directory];


您知道不应该在发布代码中使用断言,对吧?

Turns out, that in iOS and 10.5 and later, you should not use [NSFileManager defaultManager] anymore. Having used Cocoa for nearly 15 years bit me on this one. I'll leave it as a warning to others -- TechZen

Despite the many sins against good programming practice you've comitted in this code, your real problem is here:

fileManager = [[NSFileManager alloc] init];

The NSFileManger is a singleton in every app. You don't initialize it yourself, ever. The proper way to obtain the singleton is:

fileManager=[NSFileManager defaultManager];

... which returns the singleton. You usually don't bother with an attribute or variable, however, and just use it thusly:

walker = [[NSFileManager defaultManager] enumeratorAtPath:directory];


You know your not supposed to use assertions in release code, right?

情仇皆在手 2024-10-27 21:00:26

我发现同样的崩溃。在 iOS 4.3 中崩溃,但在 5.0 中运行良好。好吧。我通过代码重构以使用字符串枚举器而不是 url 枚举器:

    NSFileManager* localFileManager = [[NSFileManager alloc] init];
    NSDirectoryEnumerator* enumerator = [localFileManager enumeratorAtPath:path];
    for (NSString* file in enumerator) {
        // do stuff...
    }

祝你好运。 (并摆脱那些 goto)。

I found the same crash. Crashed in iOS 4.3 but worked fine in 5.0. Blrgh. I refactored by code to use the string enumerator instead of the url enumerator:

    NSFileManager* localFileManager = [[NSFileManager alloc] init];
    NSDirectoryEnumerator* enumerator = [localFileManager enumeratorAtPath:path];
    for (NSString* file in enumerator) {
        // do stuff...
    }

Good luck. (and get rid of those gotos).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文