gpt4 book ai didi

防止崩溃的 Objective-C 线程安全代码

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:50:38 26 4
gpt4 key购买 nike

我收到了带有 SIGSEGV 的 iPhone 崩溃报告,我想我已经缩小了可能的原因和解决方案的范围。由于线程导致的崩溃很难调试,我无法重现这个问题,但可以使用一些帮助来验证我的假设 - 它合理吗?

我的代码使用 ASIHttpRequest 使用 ASINetWorkQueue 下载一组文件。这是一个简化的示例

//initialize download queue and do this code block in a loop for each file

NSURL *fileURL = [NSURL URLWithString:...
__block ASIHTTPRequest *fileRequest = [ASIHTTPRequest requestWithURL:fileURL];

[fileRequest setCompletionBlock:^{
//do some stuff
}];
[fileRequest setFailedBlock:^{
NSString *someError = [NSString stringWithFormat:...
[self someErrorMethod:someError];
}];

[downloadQueue addOperation:...

-(void)someErrorMethod(NSString *errorMessage) {
DDLogWarn(errorMessage);

if ([self downloadQueue]) {
for (ASIHTTPRequest *request in [[self downloadQueue] operations]) {
[request clearDelegatesAndCancel];
}
[[self downloadQueue] reset];
}
}

崩溃报告的前两行是

  • libobjc.A.dylib 0x31846fbc objc_msgSend + 15
  • MyApp 0x0002cab5 -[Myapp someErrorMethod:] (MyApp.m:)

我对为什么会这样的想法

  • 文件下载失败,失败 block 被调用
  • 它遍历每个请求并清除委托(delegate)并取消它们,然后重置队列
  • 但是在till运行的过程中,又一次下载文件失败,进入失败block回调
  • 但是,由于它现在已被取消,它的失败 block 已被释放
  • 当代码尝试记录错误消息时,其内存已被释放,随之而来的是不可预知的结果

这有意义吗?由于我是 Objective-C 的新手,我的分析是正确的还是我遗漏了一些明显的东西?

我正在考虑使用锁使 errorMethod 线程安全,希望它能解决这个问题。基于上述代码,这听起来像是正确的解决方案吗?

谢谢

最佳答案

这听起来不太可能。 ASIHttpRequest 可能会在同一线程上执行其所有回调(我对此非常确定)。

如果我不得不猜测,您的错误更有可能出现在这一行:

DDLogWarn(errorMessage);

DDLogWarn 的第一个参数是格式,而不是字符串。在 errorMessage 包含 % 的任何情况下,这都可能会崩溃。你的意思是:

DDLogWarn(@"%@", errorMessage);

由于 DDLogWarn() 是一个可变参数方法,它将开始用它在堆栈上找到的(随机)值来替换字符串中的任何 % 替换。它将读取堆栈,直到用完 % 替换。如果任何 % 替换是基于指针的(如 %s 或 %@),那么它将跟随指针指向一个随机位置。

SEG_ACCERR 表示您请求了一 block 您不拥有的内存。 SEG_MAPERR 表示您请求了一 block 未映射的内存。两者都是遵循完全随机指针的预期结果。

关于防止崩溃的 Objective-C 线程安全代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9364539/

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