5

我想使用 __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];
4

3 回答 3

5

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

具体来说:

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

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

所以你需要复制。

于 2012-04-23T04:19:08.337 回答
1

使用块在这里甚至是一个问题吗?

在我看来,这个代码序列:

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

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

于 2012-04-23T05:49:16.010 回答
1

这里可以在路径上使用复制或保留。您的问题的原因是 NSString 对象是便利对象的成员,以及其他诸如 NSArray 之类的对象,您实际上不必释放它们,并且在 ARC 之前已经由系统自动释放。就个人而言,我不喜欢他们这样做,因为它只会引起这样的混乱。因为块完成执行系统会自动释放您分配的导致泄漏的字符串对象。

于 2012-04-23T04:18:20.690 回答