我有一些objective-c中的递归块代码,导致出现EXC_BAD_ACCESS错误。
- (void) doSomethingWithCompletion:(void (^)())completion {
if (completion) {
dispatch_async(dispatch_get_main_queue(), completion);
}
}
- (void) testBlocks {
NSString *testString = @"hello";
__block NSInteger count = 0;
__block __weak void (^weak_block)(NSString *);
void(^strong_block)(NSString *);
weak_block = strong_block = ^(NSString *str) {
[self doSomethingWithCompletion:^{
NSLog(@"number: %zd", count);
if (++count < 10) {
weak_block(str);
}
}];
};
strong_block(testString);
}
错误发生在 weak_block(str) 上,我认为这是因为在调用 dispatch_async 时它被释放了。在声明为 __block 时,可以将其替换为 strong_block(str)。请参考以下内容:
__block void(^strong_block)(NSString *);
出现警告“在此块中强烈捕获 'strong_block' 可能会导致保留循环”。
因此,我将 testBlock 方法更改为不使用弱引用,如下所示:
- (void) testBlocks {
NSString *testString = @"hello";
__block NSInteger count = 0;
__block void (^inner_block)(NSString *);
void(^strong_block)(NSString *);
inner_block = strong_block = ^(NSString *str) {
[self doSomethingWithCompletion:^{
NSLog(@"number: %zd", count);
if (++count < 10) {
inner_block(str);
}
}];
};
strong_block(testString);
}
但我不确定这是否会导致保留循环,或者是否添加
__block void (^inner_block)(NSString *) = weak_block;
如果在块中使用self而不是weak self,也会导致保留循环。那么处理这种情况的正确方法是什么?