gpt4 book ai didi

ios - 调用 block 内的 block 后的 BAD ACCESS (iOS)

转载 作者:行者123 更新时间:2023-12-01 18:12:16 25 4
gpt4 key购买 nike

我有一个 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com