gpt4 book ai didi

ios - 奇怪的 bad_access 与 dispatch_async

转载 作者:行者123 更新时间:2023-11-29 03:30:47 24 4
gpt4 key购买 nike

我在使用异步调度时遇到了一个非常奇怪的错误访问错误。我设法将其减少到程序中的这段代码。

-(void)buttonTapped:(id)sender {

__block NSArray*foo = nil;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
//Foo was initially declared here but then moved it outside.
foo = [self someMethod];
[foo retain]; // bad access here. Why ?
dispatch_async(dispatch_get_main_queue(),0) {
// doesnt matter what happens here
}); });
}

-(id)someMethod
{
return [self secondMethod];
}

-(id)secondMethod
{
// was initially returning an autoreleased object from here. Changed it
// to eliminate that as source of the error.
id newThing = [[NSObject alloc] init];
return newThing;
}

代码最初看起来不是这样的,但现在是这样的。包括分配一个虚拟的 NSObject 。

foo 如何在调度 async 内的调用之间被释放?我不明白这怎么可能。我知道很难建议仅此而已,但任何调试建议都会有所帮助。我尝试打开 NSZombies,但没有收到任何 Zombies。

最佳答案

你问:

How is it possible for foo to get released in between calls inside a dispatch_async?

不应该,除非someMethodsecondMethod他们自己正在异步执行某些操作,这可能会允许自动释放池在此期间被耗尽。

I tried turning on NSZombies but I dont get any Zombies.

如果您已打开僵尸但没有收到僵尸,那么我怀疑问题出在其他地方。坦率地说,我怀疑问题的根源是在您针对问题的目的简化示例代码的过程中消除的:

其他一些观察/说明:

  1. 您声明了 foo成为NSArray , 但你会返回 NSObject .我假设你的意思是 NSObject贯穿始终。

  2. 你有一行代码说:

    dispatch_async(dispatch_get_main_queue(),0) {

    我假设那是一个错字并且您是故意的:

    dispatch_async(dispatch_get_main_queue(), ^{
  3. foo变量绝对应该在 dispatch_async 内堵塞。拥有 __block 真的没有意义某物的变量 (a) 你不在该 block 之外引用一个 block ;和 (b) 对于您正在异步调度的 block 。

  4. secondMethod应该返回 autorelease对象,因为您显然最初拥有它。 (或者您可能希望将名称中的 secondMethodsomeMethod 更改为以 new 开头,以避免混淆并让您最终迁移到 ARC 时的生活更轻松。)

  5. 如果你retain foo对象,您还需要添加适当的 release .事实上,您的原始代码示例返回一个 +1 对象,然后再次保留它,将它撞到 +2,所以您需要两个 release电话。

无论如何,纠正这些不同的问题,我最终得到以下结果,它不会产生异常:

- (IBAction)buttonTapped:(id)sender
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

NSObject *foo = [self someMethod];
[foo retain]; // no bad access here

dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"foo = %@", foo);

[foo release];
});
});
}

- (NSObject *)someMethod
{
return [self secondMethod];
}

- (NSObject *)secondMethod
{
return [[[NSObject alloc] init] autorelease];
}

此外,我建议您通过静态分析器(Xcode“产品”菜单上的“分析”)运行它,尤其是在使用手动保留和释放 (MRR) 时,并确保您的健康状况良好. (它会指出我提到的一些问题。)它并不完美,但它非常擅长识别问题。

但是,简而言之,上面的代码很好,如果您仍然遇到异常,请使用可重现异常的工作代码更新您的问题。

关于ios - 奇怪的 bad_access 与 dispatch_async,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19818505/

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