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];
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With