【问题标题】:Executing button action in secondary thread在辅助线程中执行按钮操作
【发布时间】:2011-11-25 06:49:06
【问题描述】:

我想知道为什么我不能在辅助线程中运行按钮操作(请参阅下面的辅助线程代码),当我这样做时,APP 崩溃并显示以下错误消息。

NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(insertdata) object:nil];
[thread start];

void _WebThreadLockFromAnyThread(bool), 0x6a8cfe0: Obtaining the web lock from a thread other than the main thread or the web thread. UIKit should not be called from a secondary thread.

bool _WebTryThreadLock(bool), 0x6a8cfe0: Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now...

1   WebThreadLock
2   -[UIFieldEditor setText:andSetCaretSelectionAfterText:]
3   -[UITextField setText:]
4   -[XYZ reset]
5   -[XYZ insertdata]
6   -[NSThread main]
7   __NSThread__main__
8   _pthread_start
9   thread_start

但是当我将线程更改为主线程时(见下面的主线程代码)我没有看到任何崩溃并且我的 APP 运行完美。谁能解释一下有什么区别,为什么我不能运行动作辅助线程。

[self performSelectorOnMainThread:@selector(insertdata) withObject:nil waitUntilDone:NO];

谢谢。

【问题讨论】:

    标签: objective-c uibutton ios5 nsthread


    【解决方案1】:

    错误信息告诉你确切的原因:

    从主线程或主线程以外的线程获取网络锁 网络线程。不应从辅助线程调用 UIKit。

    如果操作不需要很长时间,那么在后台线程上执行它是没有意义的。如果操作确实需要很长时间,您应该将数据检索(或任何需要很长时间的操作)与 UI 更新分开,在后台运行数据检索,然后返回主线程进行更新用户界面。最好使用 GCD:

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_NORMAL, 0), ^{
        [self downloadData]; // takes long
        dispatch_async(dispatch_get_main_queue(), ^{
            [self updateUI]; // here you can safely call UIKit
        });
    });
    

    【讨论】:

    • 感谢您的澄清,所以我们只有在下载或做一些后台操作时才需要使用辅助线程操作。那么GCD(Grand Central Dispatch)是如何和副线程相似的,如何在后台运行时从副线程切换到主线程。
    • 除了 UIKit 之外,你可以使用后台线程处理大多数事情。 GCD 比显式线程管理要好得多,请阅读文档。从后台线程切换到主线程已经在上面的代码示例中说明了,这是“主队列调度”的事情。
    • 请问如何更新用户界面。假设如果我的 UI 包含名为 resultsText 的文本字段,那么 updateUI 将包含什么?
    • 可能只是[resultsText setText:@"some data"]。这部分完全取决于您的代码应该做什么。
    • 我刚刚尝试使用 resultsText.text=nil。但即使在那之后它也会导致网络线程锁定
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多