当出局时,“_ _ lock”变量导致nil值

时间:2012-04-23 03:36:42

标签: objective-c automatic-ref-counting objective-c-blocks

我想使用__block变量来获取块中的值。但是当阻塞时,__block变量似乎是零。为什么会这样呢?

    NSString *fileName = [Tools MD5Encode:url];
    __block NSString *filePath = nil;
    [fileList enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        NSString *aFileName = obj;
        if ([aFileName isEqualToString:fileName]) {
            NSString *path = [VERSIONS_INFO_DATA_DIRECTORY stringByAppendingPathComponent:aFileName];
            filePath = path;
            NSLog(@"filePath1 %@", filePath);
            *stop = YES;
        }
    }];
    //NSLog(@"filePath2 %@", filePath);
    //filePath seems to be nil
    return filePath;

当我将代码更改为[路径复制]时,它可以正常工作。但我不知道这是不是一个好主意。有任何决定吗?

    NSString *fileName = [Tools MD5Encode:url];
    __block NSString *filePath = nil;
    [fileList enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        NSString *aFileName = obj;
        if ([aFileName isEqualToString:fileName]) {
            NSString *path = [VERSIONS_INFO_DATA_DIRECTORY stringByAppendingPathComponent:aFileName];
            filePath = [path copy];
            NSLog(@"filePath1 %@", filePath);
            *stop = YES;
        }
    }];
    //NSLog(@"filePath2 %@", filePath);
    return [filePath autorelease];

3 个答案:

答案 0 :(得分:5)

http://www.mikeash.com/pyblog/friday-qa-2011-09-30-automatic-reference-counting.html

具体做法是:

  

如果没有ARC,__block还有副作用,即当它被块捕获时不保留其内容。块将自动保留并释放它们捕获的任何对象指针,但__block指针是特殊的,并充当弱指针。通过使用__block来避免保留周期,这成为依赖此行为的常见模式。

     

在ARC下,__block现在保留其内容,就像其他捕获的对象指针一样。使用__block来避免保留周期的代码将不再起作用。相反,如上所述使用__weak。

所以你需要复制。

答案 1 :(得分:1)

这里可以在路径上使用copy或retain。您遇到问题的原因是NSString对象是方便对象的成员以及NSArray之类的其他对象,您实际上不必释放这些对象,并且在ARC出现之前已经由系统自动释放。就个人而言,我不喜欢他们这样做,因为它只是造成了这样的混乱。因为块完成执行系统自动释放你分配的字符串对象导致泄漏。

答案 2 :(得分:1)

块的使用是否是一个问题?

我觉得这段代码:

NSString *filePath = nil;
NSString *path = [VERSIONS_INFO_DATA_DIRECTORY stringByAppendingPathComponent:aFileName];
filePath = path;
return [filePath autorelease];

过度释放filePath(因为你不拥有-stringByAppendingPathComponent:的结果,你不应该(自动)释放它)