“__block” variable results in nil value when go out of block
我想使用__block变量来获取块中的值。 但是当阻塞时,__block变量似乎是零。 为什么会这样?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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; |
当我将代码更改为[路径复制]时,它可以工作。 但我不知道这是不是一个好主意。 任何决定?
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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]; |
http://www.mikeash.com/pyblog/friday-qa-2011-09-30-automatic-reference-counting.html
特别:
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.
所以你需要复制。
在这里使用块甚至是一个问题吗?
在我看来这段代码:
1 2 3 4 | NSString *filePath = nil; NSString *path = [VERSIONS_INFO_DATA_DIRECTORY stringByAppendingPathComponent:aFileName]; filePath = path; return [filePath autorelease]; |
过度释放
这里可以使用路径上的复制或保留。 您遇到问题的原因是NSString对象是方便对象的成员以及NSArray之类的其他对象,您实际上不必释放这些对象,并且在ARC出现之前已经由系统自动释放。 就个人而言,我不喜欢他们这样做,因为它只是造成了这样的混乱。 因为块完成执行系统自动释放您分配的字符串对象导致泄漏。