开发者

NSFileManager and NSDirectoryEnumerator Crash?

开发者 https://www.devze.com 2023-02-16 08:28 出处:网络
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.

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 isDire开发者_运维问答ctory:&isDirectory] && !isDirectory)
            [files addObject:file];
    }

EARLY_EXIT:

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

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

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


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?


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).

0

精彩评论

暂无评论...
验证码 换一张
取 消