我有一个 block ,我正在从 firebase 检查用户的状态属性。如果状态属性是“免费”,我想从 block 中返回,否则我想搜索另一个用户并检查他们的状态,直到找到一个“免费”用户:
void( ^ myResponseBlock)(BOOL finished) = ^ void(BOOL finished) {
if (finished) {
if ([self.freedom isEqualToString: @"free"]) {
NSLog(@"free!");
return;
} else if ([self.freedom isEqualToString: @"matched"]) {
NSLog(@"get another user");
//get another user
do {
//picking another random user from array
rando = arc4random_uniform(arraycount);
}
while (rando == randomIndex && rando == [self.randString intValue]);
self.randString = [NSString stringWithFormat: @"%u", rando];
[users removeAllObjects];
[users addObject:usersArray[rando]];
self.freeUser = users.firstObject;
NSLog(@"set up another check");
//error is called after this block is called here, again
[self checkIfFree: myResponseBlock];
} else {
NSLog(@"error!");
}
} else {
NSLog(@"not finished the checking yet");
}
};
[self checkIfFree: myResponseBlock];
如图所示,当在下面的“compblock(YES)”行第二次调用该 block 时,我收到“BAD ACCESS”错误:
-(void)checkIfFree:(myCompletion) compblock{
self.freeUserFB = [[Firebase alloc] initWithUrl:[NSString stringWithFormat: @"https://skipchat.firebaseio.com/users/%@", self.freeUser.objectId]];
[self.freeUserFB observeEventType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot)
{
self.otherStatus = snapshot.value[@"status"];
NSLog(@"snapshot info %@", snapshot.value);
if ([self.otherStatus isEqualToString:@"free"]) {
self.userIsFree = YES;
self.freedom = @"free";
NSLog(@"user is free in the check method %@", self.freedom);
}
else{
self.userIsFree = NO;
self.freedom = @"matched";
NSLog(@"user is matched in the check method %@", self.freedom);
}
compblock(YES);
}];
}
如果不必召回该 block 并且检查的第一个用户已经“空闲”,那么一切都很好。我不知道为什么会出现此错误/崩溃,并且想知道如何解决它!
谢谢!
最佳答案
一个 block
捕获所有传入的变量,包括它自己,但是变量 myResponseBlock
尚未在 block 内初始化。因此,您调用checkIfFree
带有 nil
的方法值进而导致应用程序崩溃。
您可以做的一件事就是将您的 block 声明为 __block
多变的。
__block __weak void(^weakResponseBlock)(BOOL);
void(^myResponseBlock)(BOOL);
weakResponseBlock = myResponseBlock = ^void(BOOL finished) {
...
if (weakResponseBlock) {
[self checkIfFree:weakResponseBlock];
}
}
此外,请注意 block 保留传递给它们的所有变量。在这种情况下,您将 self 保留在 block 内,因此只要 block 执行,它就永远不会被释放。因此,除非另有要求,否则始终传递对 block 的弱引用。
__weak UIViewController *weakSelf = self;
weakResponseBlock = myResponseBlock = ^void(BOOL finished) {
...
if (weakResponseBlock) {
[weakSelf checkIfFree:weakResponseBlock];
}
}
关于ios - 调用 block 内的 block 后的 BAD ACCESS (iOS),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28388668/