gpt4 book ai didi

ios - GCD 异步 block & EXC_BAD_ACCESS

转载 作者:可可西里 更新时间:2023-11-01 06:10:31 24 4
gpt4 key购买 nike

这种崩溃相当罕见,但它发生的次数足以让我确信我做错了。

这是在自定义并发队列上使用主线程异步分派(dispatch)和屏障分派(dispatch)执行的 API 调用(使用屏障是因为我们正在通过对同一队列的非屏障调用修改在别处读取的数据)。

目标是异步发出 HTTP 请求,然后触发 dispatch_barrier_async 来处理结果数据。

当 dispatch_barrier_async 调用正在复制传递的 block 中使用的变量时,就会发生崩溃。我想该变量在 block 中使用之前已被释放,但考虑到我声明它的方式(作为 __block 变量),我看不出这是怎么发生的(除非问题出在赋值运算符...)。

这是堆栈跟踪:


#0 0x00004f44 in __Block_byref_object_copy_ at /blah/ABEvent.m:156
#1 0x0000582d in __copy_helper_block_ at /blah/ABEvent.m:191
#2 0x02cf3be2 in _Block_call_copy_helper ()
#3 0x02cf3681 in _Block_copy_internal ()
#4 0x02c25526 in _dispatch_Block_copy ()
#5 0x02c26802 in dispatch_barrier_async ()
#6 0x00004e71 in __18+[ABEvent fetch]_block_invoke at /blah/ABEvent.m:159
#7 0x00056e77 in __88-[ABClient get:parameters:success:failure:]_block_invoke_2 at /blah/ABClient.m:375
#8 0x02c2553f in _dispatch_call_block_and_release ()
#9 0x02c37014 in _dispatch_client_callout ()
#10 0x02c277d5 in _dispatch_main_queue_callback_4CF ()
#11 0x02facaf5 in __CFRunLoopRun ()
#12 0x02fabf44 in CFRunLoopRunSpecific ()
#13 0x02fabe1b in CFRunLoopRunInMode ()
#14 0x02f517e3 in GSEventRunModal ()
#15 0x02f51668 in GSEventRun ()
#16 0x01ef1ffc in UIApplicationMain ()
#17 0x0005164d in main at /blah/main.m:3
#18 0x00002db5 in start ()

还有代码:


+ (void)fetch {
ABBlock _success = ^(ABMessage *m) {

__block NSMutableArray *fetched = [NSMutableArray arrayWithArray:m.params[@"live"]];
[fetched addObjectsFromArray:m.params[@"soon"]]; // EXC_BAD_ACCESS (top of stack)

dispatch_barrier_async([ABEvent eventQueue], ^{ // CRASHED IN BLOCK INVOKE (stack line 6)
NSMutableArray *events = [NSMutableArray array];

for (NSDictionary *d in fetched) {
[events addObject:[ABEvent eventWithDictionary:d]];
}

AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
appDelegate.events = events;

events = nil;
});
};

[[ABClient sharedInstance] events:_success failure:nil];
}

上游:



-(void)events:(ABBlock)success failure:(ABBlock)failure {
NSString *params = [NSString stringWithFormat:@"%@",[ABUser loggedInUser]? [ABUser loggedInUser].name : @"no"];
NSDictionary *dict = @{@"loggedIn": params};

[self get:@"events/live.json" parameters:dict success:success failure:failure];
}

- (void)get:(NSString *)path
parameters:(NSDictionary *)parameters
success:(ABBlock)success
failure:(ABBlock)failure

__block ABBlock blockSuccess = success;
__block ABBlock blockFailure = failure;
NSString *blockPath = path;
NSDictionary *blockParameters = parameters;

AFHTTPSuccessBlock _success = ^(AFHTTPRequestOperation *request, id response) {
if (blockSuccess) {
ABMessage *msg = [ABMessage messageWithObject:response];
dispatch_async(dispatch_get_main_queue(), ^(void) {
blockSuccess(msg);
});
}

};
}

Elsewhere:

typedef void (^ABBlock) (ABMessage *);

barrier_async block 使用变量的方式有什么明显的错误吗?我想知道我是否应该复制作为参数传入的消息 (*m)。

最佳答案

尝试创建对它的强引用,例如:

        ABMessage *msg = [ABMessage messageWithObject:response];
dispatch_async(dispatch_get_main_queue(), ^(void) {
ABMessage *m = msg;
blockSuccess(m);
});

关于ios - GCD 异步 block & EXC_BAD_ACCESS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16286242/

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