在NSOperationQueue非主队列上创建UI元素会导致奇怪的行为 [英] creating UI elements on NSOperationQueue non-main queues causes strange behavior

查看:105
本文介绍了在NSOperationQueue非主队列上创建UI元素会导致奇怪的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些代码通过 [[NSOperationQueue alloc] init]创建的队列创建并添加了 UIView 子视图,它导致了奇怪的滞后行为。仅在异常长时间延迟后才添加子视图。

I had some code that created and added UIView subviews via a queue created by [[NSOperationQueue alloc] init], and it led to strangely laggy behavior. Subviews were only added after abnormally long delays.

然后我切换到使用 [NSOperationQueue mainQueue] 这些部件,响应能力正常。

But then I switched to using [NSOperationQueue mainQueue] for these parts, and responsiveness turned normal.

我只想解释一下我用第一种方法看到的滞后行为。

I would just like an explanation for the laggy behavior I saw using the first approach.

推荐答案

来自Apple doc

From Apple doc


主题和用户界面

如果您的应用程序具有图形用户界面,建议您从
应用程序的主线程接收
用户相关事件并启动界面更新。 此方法有助于避免与处理用户事件和绘制窗口
内容相关的同步
问题。
某些框架(如Cocoa)通常需要此
行为,但即使对于那些没有,在
主线程上保持这种行为有利于简化管理
用户界面的逻辑。有一些值得注意的例外,其中
有利于从其他线程执行图形操作。对于
示例,QuickTime API包括许多操作,可以是从辅助线程执行的
,包括打开电影文件,
渲染电影文件,压缩电影文件,以及导入和
导出图像。类似地,在Carbon和Cocoa中,您可以使用辅助
线程来创建和处理图像,并执行其他与图像相关的
计算。使用辅助线程进行这些操作可以大大提高性能。 如果您不确定特定的图形化
操作,请计划从主线程执行此操作

If your application has a graphical user interface, it is recommended that you receive user-related events and initiate interface updatesfrom your application’s main thread. This approach helps avoid synchronization issues associated with handling user events and drawing window content. Some frameworks,such as Cocoa, generally require this behavior, but even for those that do not, keeping this behavior on the main thread hasthe advantage of simplifying the logic for managing your user interface. There are a few notable exceptions where it is advantageous to perform graphical operations from other threads. For example, the QuickTime API includes a number of operationsthat can be performed from secondary threads, including opening movie files, rendering movie files, compressing movie files, and importing and exporting images. Similarly, in Carbon and Cocoa you can use secondary threads to create and process images and perform other image-related calculations. Using secondary threads for these operations can greatly increase performance. If you are not sure about a particular graphical operation though, plan on doing it from your main thread

此外,根据线程编程指南

因此,请避免从与主线程不同的线程更新UI。

如果您运行 NSOperation (在队列中),您可以更新您的UI(例如在下载之后)您的应用生命周期所需的数据)在主线程中执行方法,如下所示:

If you run an NSOperation (within a queue) you could update your UI (for example after having download some data required for your app lifecycle) performing a method in the main thread like the following:

-(void)main {

    // e.g the delegate could be the controller that has the view that you want to update
    if (delegate) {

        NSURL *url = [delegate urlForDownloadOperation:self];
        if ( nil == url ) return;
        self.downloadedImage = [[NSImage alloc] initWithContentsOfURL:url];

        // e.g. rather than invoking processImage directly on the delegate, ensure that the method draw the image on the main thread
        [delegate performSelectorOnMainThread:@selector(processImage:) 
            withObject:self waitUntilDone:YES];
    }
}

或者您可以向需要的组件发送通知更新UI如:

Or you could send a notification to the component that need to update the UI like:

- (void)main {

   NSURL *url = [delegate urlForDownloadOperation:self];
   if ( nil == url ) return;
   self.downloadedImage = [[NSImage alloc] initWithContentsOfURL:url];

   // e.g. send a notificatio to inform some components that it is ready to update the UI with some content
   [[NSNotificationCenter defaultCenter] postNotificationName:@"importData" object:self];
}

需要更新UI的组件将注册该通知,如

The component that needs to update the UI will register for that notification like

- (void)processImage:(NSNotification*)notification
{
    if (![NSThread isMainThread]) {
        [self performSelectorOnMainThread:@selector(processImage:) withObject:notification waitUntilDone:YES];
        return;
    }

    // update the UI here, you are running on the main thread
}

这篇关于在NSOperationQueue非主队列上创建UI元素会导致奇怪的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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