用于防止崩溃的 Objective-C 线程安全代码
<p><p>我收到了一份带有 SIGSEGV 的 iPhone 崩溃报告,我想我已经缩小了可能的原因并找到了解决方案。
由于线程导致的崩溃很难调试,因此我无法重现此问题,但可以对我的假设提供一些帮助 - 是否合理?</p>
<p>我的代码使用 ASIHttpRequest 通过 ASINetWorkQueue 下载一组文件。这是一个简化的示例</p>
<pre><code>//initialize download queue and do this code block in a loop for each file
NSURL *fileURL = [NSURL URLWithString:...
__block ASIHTTPRequest *fileRequest = ;
[fileRequest setCompletionBlock:^{
//do some stuff
}];
[fileRequest setFailedBlock:^{
NSString *someError = [NSString stringWithFormat:...
;
}];
[downloadQueue addOperation:...
</code></pre>
<hr/>
<pre><code>-(void)someErrorMethod(NSString *errorMessage) {
DDLogWarn(errorMessage);
if () {
for (ASIHTTPRequest *request in [ operations]) {
;
}
[ reset];
}
}
</code></pre>
<hr/>
<p>崩溃报告的前两行是</p>
<ul>
<li>libobjc.A.dylib 0x31846fbc objc_msgSend + 15</li>
<li>MyApp 0x0002cab5 - (MyApp.m:)</li>
</ul>
<hr/>
<p>我对为什么会发生这种情况的想法</p>
<ul>
<li>文件下载失败,调用失败的 block </li>
<li>它遍历每个请求并清除委托(delegate)并取消它们,然后重置队列</li>
<li>但是,在运行前,另一个文件下载失败,进入失败 block 回调</li>
<li>但是,由于现在已经被取消,所以它的失败 block 已经被释放了</li>
<li>当代码尝试记录错误消息时,它的内存已被释放,并且会出现不可预知的结果</li>
</ul>
<p>这有意义吗?由于我是 Objective-C 的新手,我的分析是正确的还是我遗漏了一些明显的东西?</p>
<p>我正在考虑使用锁来使 errorMethod 线程安全,希望它能解决这个问题。根据上面的代码,这听起来像是正确的解决方案吗?</p>
<p>谢谢</p></p>
<br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
<p><p>这听起来不太可能。 <code>ASIHttpRequest</code> 可能在同一个线程上执行其所有回调(我对此相当肯定)。</p>
<p>如果我不得不猜测,您的错误更有可能出现在这一行:</p>
<pre><code>DDLogWarn(errorMessage);
</code></pre>
<p><code>DDLogWarn</code> 的第一个参数是格式,而不是字符串。在 <code>errorMessage</code> 包含 % 的任何情况下,这都可能会崩溃。你的意思是:</p>
<pre><code>DDLogWarn(@"%@", errorMessage);
</code></pre>
<hr/>
<p>由于 <code>DDLogWarn()</code> 是一个 varags 方法,它将开始用它在堆栈中找到的(随机)值替换字符串中的任何 % 替换。它将读取堆栈,直到您用完 % 替换。如果任何 % 替换是基于指针的(如 %s 或 %@),那么它将跟随指针指向随机位置。</p>
<p>SEG_ACCERR 表示您请求了一 block 您不拥有的内存。 SEG_MAPERR 表示您请求了一 block 未映射的内存。要么是遵循完全随机指针的预期结果。</p></p>
<p style="font-size: 20px;">关于用于防止崩溃的 Objective-C 线程安全代码,我们在Stack Overflow上找到一个类似的问题:
<a href="https://stackoverflow.com/questions/9364539/" rel="noreferrer noopener nofollow" style="color: red;">
https://stackoverflow.com/questions/9364539/
</a>
</p>
页:
[1]