【发布时间】:2012-02-20 16:24:09
【问题描述】:
我收到了一份带有 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:)
我对为什么会发生这种情况的想法
- 文件下载失败,调用失败的块
- 它遍历每个请求并清除委托并取消它们,然后重置队列
- 但是,在运行前,另一个文件下载失败,进入失败块回调
- 但是,由于它现在已被取消,其失败的块已被释放
- 当代码尝试记录错误消息时,它的内存已被释放,并且会出现不可预知的结果
这有意义吗?由于我是 Objective-C 的新手,我的分析是正确的还是我遗漏了一些明显的东西?
我正在考虑使用锁来使 errorMethod 线程安全,希望它能解决这个问题。根据上面的代码,这听起来像是正确的解决方案吗?
谢谢
【问题讨论】:
-
不确定您的错误,但您可能想检查一下:stackoverflow.com/a/5023583/330494 您应该使用 blocksafeSelf 来引用 self with an ivar 块。
-
谢谢 Barlow 我在这里使用了一个永远不会被释放的单例类,所以我认为保留周期不是问题,对吧?
标签: objective-c ios crash thread-safety block