gpt4 book ai didi

ios - 在 iOS9.1 中什么可以触发 dispatch_async 上的 SIGABRT?

转载 作者:可可西里 更新时间:2023-11-01 03:33:35 24 4
gpt4 key购买 nike

我正在尝试调试该领域的许多用户报告的崩溃错误。都显示相同的堆栈:

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Triggered by Thread: 8
OS Version: iOS 9.1 (13B143)
Code Type: ARM (Native)

0 libsystem_kernel.dylib 0x392ccc84 0x392b8000 + 85124
1 libsystem_pthread.dylib 0x39370732 0x3936c000 + 18226
2 libsystem_c.dylib 0x39264f9a 0x3921a000 + 307098
3 libsystem_c.dylib 0x39264f2c 0x3921a000 + 306988
4 libsystem_c.dylib 0x392447ea 0x3921a000 + 174058
5 MyApp 0x000cb3e0 __69-[MyDataManager myMethod:]_block_invoke (MyDataManager.m:2367)

第 2367 行很简单:

2363: BOOL success = [db executeUpdate:@"INSERT INTO table (id, content) VALUES (?, ?)", message.remoteId, message.content];
2364: assert(success);
2365: DebugLog(@"DB Results %d", success);
2366:
2367: dispatch_async(dispatch_get_main_queue(), ^{
2368: [self cleanupMethod:args];
2369: });

虽然该 block 中肯定有代码,但它只有 1 行长,而且该代码似乎并未在此堆栈上执行,否则我会在 myMethod cleanupMethod.

编辑:您可以看到,就在 dispatch_async 之前,有一个断言!我本来以为这次崩溃是assert引起的。但是行号从来没有匹配过——断言在上面有很多行(第 2364 行,而不是 2367 行)——当我进一步测试它时,我发现如果断言被触发,我的堆栈将不包括 _block_invoke,您可以看到它附加到对 myMethod 的调用末尾。

谁能建议 dispatch_async 如何触发这种行为?另外,我有什么办法可以在libsystem_c.dylib中符号化Apple的代码吗?

libsystem_c.dylib 的二进制镜像:

0x3921a000 - 0x3927efff libsystem_c.dylib armv7  <0b5d65608e6f38448cd207fbd748d372> /usr/lib/system/libsystem_c.dylib

注意:所讨论的对象是一个全局单例,如果你愿意的话,我的“数据管理器”。它处理网络请求并存储可能需要在 UIViewController 之间共享的状态。最初声明如下:

+ (MyDataManager *)mainStore {
static dispatch_once_t once;
static id sharedInstance;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] init];
});

return sharedInstance;
}

我理解当我的 cleanupMethod:args 方法被调用时对象被释放的后果...但是我认为我的全局单例会一直存在,因此以我在代码中的方式调用总是安全的吗?我也不关心保留周期,因为这应该是一个全局单例。

下面的代码示例是否可以执行?

@interface MyDataManager
@end

@implementation MyDataManager

+ (MyDataManager *)mainStore {
static dispatch_once_t once;
static id sharedInstance;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] init];
});

return sharedInstance;
}

- (void)myMethod {
NSDictionary *args = @{...}
...
dispatch_async(dispatch_get_main_queue(), ^{
[self cleanupMethod:args];
});
}

- (void)cleanupMethod:(id)args {
...
}

@end

@interface MyViewController : UIViewController
@end

@implementation MyViewController

- (void)viewDidLoad {
[super viewDidLoad];
[[MyDataManager sharedInstance] myMethod];
}

@end

最佳答案

看起来问题出在对 self 的强引用中,这会使您的应用程序崩溃,显然是在调用已释放的 self 时。此代码将生成一个新变量,该变量将存储对 selfweak 引用,这应该可以解决问题:

__weak typeof(self)weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf cleanupMethod:args];
});

有人会说你必须在这里使用 __strong typeof(weakSelf)strongSelf = weakSelf; 来对弱引用进行强引用,以避免强引用循环但保持self 还活着,但我不想在这里这样做,以防 self 在 block 执行时为 nil - nil 的消息在 objective-c 中完全没问题,所以什么也不会发生。

加上行之前发生的堆栈跟踪

0x000cb3e0 __69-[MyDataManager myMethod:]_block_invoke (MyDataManager.m:2367)

肯定有助于诊断问题。

编辑:好吧,您在访问共享对象时似乎没有使用类方法 mainStore。也许这就是问题所在。

关于ios - 在 iOS9.1 中什么可以触发 dispatch_async 上的 SIGABRT?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33326860/

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