死锁:如何确定调用是否可能导致iOS主线程的绘画不安全? [英] Deadlocks: How do you determine if a call may cause unsafe painting off of the main thread for iOS?

查看:60
本文介绍了死锁:如何确定调用是否可能导致iOS主线程的绘画不安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

绘图/绘画应始终在GUI线程上进行,否则可能发生死锁!...

Drawing/painting should always be done on the GUI thread otherwise deadlocks can occur!...

如何确定调用是否可能导致不安全的绘画iOS的主线程?

How do you determine if a call may cause unsafe painting off of the main thread for iOS?

问题是我们得到的堆栈不在主线程上……

The problem is we get stacks like this which are not on the main thread...

#19 0x02a788d2 in -[CALayer drawInContext:]
#20 0x02a784b0 in backing_callback
#21 0x02a77d52 in CABackingStoreUpdate
#22 0x02a7701d in -[CALayer _display]
#23 0x02a76ac7 in CALayerDisplayIfNeeded
#24 0x02a689e1 in CA::Context::commit_transaction
#25 0x02a68732 in CA::Transaction::commit
#26 0x02aa604f in CA::Transaction::release_thread
#27 0x918b21e3 in _pthread_tsd_cleanup
#28 0x918b1df6 in _pthread_exit
#29 0x0018bbf2 in +[NSThread exit]
#30 0x0018bb5b in __NSThread__main__
#31 0x918a981d in _pthread_start
#32 0x918a96a2 in thread_start

如何查找如果你要去g造成这个?
是否有任何调试技巧或其他技术可在您做错事时提醒您自己。

How do you find out if you're going to cause this? Are there any debugging tips or other techniques to alert yourself when you do something wrong.

推荐答案

在进行任何操作之前可能会引起一些绘图,您应该确保自己在主线程上。

Before manipulating anything that can cause some drawing, you should make sure you're on the main thread.

例如,如果您想从分离的线程中重新加载UITableView,则应调用:

For instance if you want to reload a UITableView from a detached thread, you should call:

[myTableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];

如果您有多个可能导致绘图的语句,则可以有一个单独的方法来绘图并确保它在主线程上执行:

And if you have several statements that can cause drawing, you can have a separate method that do the drawing and make sure it's performed on the main thread:

- (void) asyncDoSomeStuff {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    // Do your stuff
    ...

    // Update UI
    [self performSelectorOnMainThread:@selector(refreshGUI) withObject:nil waitUntilDone:NO];

    [pool release];
}

- (void) refreshGUI {
    [myTableView reloadData];
    [myImageView setImage:[UIImage imageNamed:@"blabla.png"]];
    ...
}

最后,如果您不确定哪个线程将调用执行某些绘图的特定方法,然后在该方法的开头可以添加以下语句,这将确保整个方法将在主线程上执行:

And lastly if you're unsure about which thread is going to call a particular method that perform some drawing, then at the beginning of the method you can add the following statement, which will ensure that the whole method is going to execute on the main thread:

- (void) myMethod {
    if(![NSThread isMainThread]) {
        [self performSelectorOnMainThread:@selector(myMethod) withObject:nil waitUntilDone:NO];
        return;
    }

    // Do your stuff
}

否则,我认为没有解决方案可以检测到是否要在主线程之外执行某些绘图。例如,与UIKit相关的任何事情都应该在主线程中发生。

Otherwise I don't think there is a solution to detect that some drawing is going to be performed outside of the main thread. For instance, anything related to UIKit should occur in the main thread.

这篇关于死锁:如何确定调用是否可能导致iOS主线程的绘画不安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆