Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"__block" variable results in nil value when go out of block

I wanna use __block variable to get value in block. But when out of block, the __block variable seems to be nil. Why this would happen?

    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;

When I change the code to [path copy], it works. But I have no idea whether this is a good idea. Any decision?

    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];
like image 372
Wayne Avatar asked Apr 23 '12 03:04

Wayne


People also ask

Can a block reference an object at the function level?

At function level are __block variables. These are mutable within the block (and the enclosing scope) and are preserved if any referencing block is copied to the heap. const imports. Finally, within a method implementation, blocks may reference Objective-C instance variables—see Object and Block Variables.

What is the use of a block in Objective-C?

Blocks provide support for Objective-C and C++ objects, and other blocks, as variables. When a block is copied, it creates strong references to object variables used within the block. If you use a block within the implementation of a method: If you access an instance variable by value, a strong reference is made to the variable.

What are the limitations of a __block variable?

There are two further restrictions on __block variables: they cannot be variable length arrays, and cannot be structures that contain C99 variable-length arrays. Blocks provide support for Objective-C and C++ objects, and other blocks, as variables. When a block is copied, it creates strong references to object variables used within the block.

What is the interaction between a block and a variable?

This article describes the interaction between blocks and variables, including memory management. Within the block object’s body of code, variables may be treated in five different ways. At function level are __block variables.


1 Answers

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

Specifically:

Without ARC, __block also has the side effect of not retaining its contents when it's captured by a block. Blocks will automatically retain and release any object pointers they capture, but __block pointers are special-cased and act as a weak pointer. It's become a common pattern to rely on this behavior by using __block to avoid retain cycles.

Under ARC, __block now retains its contents just like other captured object pointers. Code that uses __block to avoid retain cycles won't work anymore. Instead, use __weak as described above.

So you need to copy.

like image 160
Tim Reddy Avatar answered Sep 22 '22 17:09

Tim Reddy