如何在等待调用委托时让主线程进入睡眠状态?

Posted

技术标签:

【中文标题】如何在等待调用委托时让主线程进入睡眠状态?【英文标题】:How can I get the main thread to sleep while waiting for a delegate to be called? 【发布时间】:2010-05-10 10:23:02 【问题描述】:

考虑一个具有这些方法的类:

- (id) initWithFrame: (CGRect) frame

    if (!(self = [super init]))
        return nil;
    webView = [[UIWebView alloc] initWithFrame:frame];
    [webView setDelegate:self];
    lock = [[NSConditionLock alloc] initWithCondition:LOCK_WAIT];
    return self;


- (void) sethtml: (NSString *) html

    [lock lockWhenCondition:LOCK_WAIT];
    [webView loadHTMLString:html baseURL:nil];
    [lock unlock];


- (void)webViewDidFinishLoad:(UIWebView *)aWebView

    [lock lockWhenCondition:LOCK_WAIT];
    // Locking to be able to unlock and change the  condition.
    [lock unlockWithCondition:LOCK_GO];


- (NSString *) stringByEvaluatingjavascriptFromString: (NSString *) jsCommand

    [lock lockWhenCondition:LOCK_GO];
    NSString * res = [webView stringByEvaluatingJavaScriptFromString:jsCommand];
    [lock unlock];
    return res;

我们称这个类为SynchronousUIWebView。 从我执行的主线程:

webView = [[SynchronousUIWebView alloc] initWithFrame:frame];
[webView setHTML:html];
[webView stringByEvaluatingJavaScriptFromString:jsCommand];

问题似乎是在我离开当前调用堆栈之前不会调用委托,因为我正在等待委托调用发生,也就是死锁。对我来说,委托调用似乎被推送到当前调用完成时调用的队列。所以问题是我可以修改这种行为吗?

注意:需要这样做的原因是在加载 HTML 之前我无法执行 JavaScript。

【问题讨论】:

【参考方案1】:

您不能使用主线程以外的UIWebView。所以你可以省去所有的锁,让 web 视图和运行循环处理你的委托调用。然后也应该从主线程调用委托方法。

main-thread-only 问题存在于几个 Cocoa 类中,包括所有 UIKit。这意味着,所有这些类的实现都依赖于仅从主线程调用(例如,它们隐式使用主线程的运行循环)。根本不可能在其他线程上使用它们,即使在实现您自己的锁定时也是如此。

【讨论】:

以上是关于如何在等待调用委托时让主线程进入睡眠状态?的主要内容,如果未能解决你的问题,请参考以下文章

java线程

如何在最小化或睡眠时让 JS 代码在移动设备上运行

让 Android 进入睡眠状态以进行测试

c# Thread.Sleep(1000); 问题

睡眠方法和多线程的产量方法有什么区别?

唤醒一个处于睡眠状态的 QThread?