使用detachNewThreadSelector进行iOS冻结和线程处理

时间:2013-02-12 04:36:27

标签: ios multithreading thread-safety

我正在处理由其他人设计的应用程序。该应用程序充满了这样的调用:

[NSThread detachNewThreadSelector:@selector(loadPhotoImage) toTarget:self withObject:nil];

DownloadPhotoThread *thread = [[DownloadPhotoThread alloc] initWithFriendArray:_friendsList delegate:self];
[self.arrDownloadThreads addObject:thread];
[thread start];

随机我将进入整个ui锁定的情况,并且手机/模拟器不再响应触摸。为了清楚起见,该设备永远不会解冻。如果我在调试会话期间点击暂停,我会看到一个线程位于start或detachNewThreadSelector行。

今天,当这些锁发生时,我能够缩小原因。我刚刚添加了Zendesk表单控制器(在这里找到:https://github.com/zendesk/zendesk_ios_sdk/blob/master/DropboxSampleApp/FormViewController.m

具有以下代码:

- (void) textViewDidChange:(UITextView *)textView
{
    [self.tableView beginUpdates];
    [self.tableView endUpdates];
}
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row > 1) {
        CGSize s = [description sizeThatFits:CGSizeMake(description.frame.size.width, 10000)];
        float dh = MAX(s.height, 115);
        description.frame = CGRectMake(description.frame.origin.x, 
                                   description.frame.origin.y, 
                                   description.frame.size.width, 
                                   dh);
        return dh;
    }
    return 44.0;
}

我可以通过键入一个字符轻松重现锁定条件,然后反复返回到此文本框中。 (这会调整表格视图的高度)

在某些情况下,我可以通过使用dispatch_async()块包装违规者来阻止锁定条件:

DownloadPhotoThread *thread = [[DownloadPhotoThread alloc] initWithFriendArray:_friendsList delegate:self];
[self.arrDownloadThreads addObject:thread];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [thread start];
});

但在其他情况下,我不能,因为违规代码位于复杂的库中,例如ASIHTTPRequest或XMPPFramework。你对这里到底发生了什么有什么建议吗?

另一件事。当我在这种情况下暂停时,这就是主线程所说的:

Thread 1
com.apple.main-thread
0 objc_msgSend
....
25 UIApplicationMain
26 main

暂停和取消暂停将始终在objc_msgSend中的某些汇编指令中找到main。

感谢您的帮助,因为我在这里感到非常难过。

1 个答案:

答案 0 :(得分:1)

事实证明,崩溃是由https://github.com/zendesk/zendesk_ios_sdk/中的错误引起的。我已提出拉取请求并提交给他们进行审核。