如何让我的应用程序响应更快?

发布于 2024-09-25 12:49:41 字数 3034 浏览 2 评论 0原文

背景

这与我的上一个问题,但大纲视图没有获取谓词。

  • 我有一个显示 TrainingGroup 实体的 NSOutlineView

  • NSOutlineView 绑定到 NSTreeController

  • < p>在 NSTreeController 中,我勾选了“保留选择”,未勾选“选择插入的对象”。

  • 每个 TrainingGroup 代表本地计算机上的一个文件夹。

  • 每个 TrainingGroup 都可以分配给一个项目。该项目应传播到该组的所有后代。

  • 项目列与每个培训组的项目属性绑定。

  • 此视图中有大量数据。因为每次条目都有一个条目,所以在一个训练视图下总共可以有大约 15000 个后代。

大纲视图

树如下所示:

Name                       Project              
Users                      nil                  
  John                     nil                       
    Documents              nil                  
      Acme Project         Acme Project         
        Proposal.doc       Acme Project         
          12:32-12:33      Acme Project         
          13:11-13:33      Acme Project         
          ... thousands more here!                               
        Budget.xls         Acme Project         
      Big Co Project       Big Co Project       
        Deadlines.txt      Big Co Project       
        Spec.doc           Big Co Project       
      New Project          nil                  
        StartingUp.doc     nil                  
      Personal Stuff       Personal             
        MyTreehouse.doc    Personal             
    Movies                 nil                  
      Aliens.mov           nil                  
      StepMom.mov          nil                  

在项目分配时

  • 编辑项目时,对所有子项的分配发生在 NSOperation 上后台线程上的子类,以便用户可以自由地进行其他选择并在处理所有后代时四处移动。

  • 操作完成后,我在主托管对象上下文上运行 mergeChangesFromContextDidSaveNotification: 方法:

    mainContext = [[NSApp delegate] ManagedObjectContext]; [mainContext PerformSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:通知 waitUntilDone:YES];

  • 从功能上来说,这工作得很好 - 当上下文合并回 main 时,所有后代都被分配给项目。

问题

  • 合并时,绑定到主上下文的 NSOutlineView 会冻结,并且合并可能需要几秒钟才能完成。

  • 为了减少这种冻结,我已将组分批分配给几个较小的操作。

这种批量后台操作方法存在三个问题:

  1. 界面在不到一秒的时间内变得无响应。这不是什么大问题,但它确实意味着界面中会出现不可预测的小暂停。

  2. 大纲视图更新合并回的每个批次。执行此操作时,选择可能会出现问题。

  3. 指定组下的某些项目仍为空白。该对象已分配给项目,但大纲视图尚未正确刷新项目。大概是因为主线程被合并中断了。

您可以在我录制的截屏视频中看到这些问题:

http://screenr.com/Fk4

替代方案

我可以选择的 将每个操作的更改合并到在后台线程上运行的托管对象上下文中。也许我可以向主线程发送一条消息来刷新顶级组中已更改的所有对象。

这可能会解决上面的问题 1 和 3,但我认为 2 仍然是一个问题。

我的问题

有更好的方法吗?

在我开始重新设计如何执行此操作之前(我已经更改过一次它的工作方式)我想知道是否有更好的方法或有任何方法我不知道这种方法的缺点。

预先感谢您对替代方案的任何建议。

Background

This is the same background as my previous question, except the Outline view doesn't have a fetch predicate.

  • I've got an NSOutlineView that shows TrainingGroup entities.

  • The NSOutlineView is bound to an NSTreeController

  • In the NSTreeController, I've got "Preserve Selection" ticked and "Select inserted objects" unticked.

  • Each TrainingGroup represents a folder on the local machine.

  • Each TrainingGroup can be assigned to a project. The project should propagate to all descendants of that group.

  • The project column is bound to the project property of each training group.

  • There's a lot of data in this view. Because each time entry has an entry, there can be a total of ~15000 descendants under one training view.

Outline View

The tree looks like this:

Name                       Project              
Users                      nil                  
  John                     nil                       
    Documents              nil                  
      Acme Project         Acme Project         
        Proposal.doc       Acme Project         
          12:32-12:33      Acme Project         
          13:11-13:33      Acme Project         
          ... thousands more here!                               
        Budget.xls         Acme Project         
      Big Co Project       Big Co Project       
        Deadlines.txt      Big Co Project       
        Spec.doc           Big Co Project       
      New Project          nil                  
        StartingUp.doc     nil                  
      Personal Stuff       Personal             
        MyTreehouse.doc    Personal             
    Movies                 nil                  
      Aliens.mov           nil                  
      StepMom.mov          nil                  

On Project Assign

  • When a project is edited, the assignment to all children happens on an NSOperation subclass on a background thread so the user is free to make other selections and move around whilst all descendants are processed.

  • When the operation has finished, I run the mergeChangesFromContextDidSaveNotification: method on the main managed object context:

    mainContext = [[NSApp delegate] managedObjectContext];
    [mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
    withObject:notification
    waitUntilDone:YES];

  • Functionally, this works fine - all descendants are assigned to the project when the context is merged back into main.

The Problem

  • On merge, the NSOutlineView that's bound to the main context freezes and the merge can take several seconds to complete.

  • To reduce this freeze, I've batched up the groups to assign into several smaller operations.

There are three problems with this batched background operation approach:

  1. The interface becomes unresponsive for a fraction of a second. This isn't such a big deal, but it does mean small unpredictable pauses in the interface.

  2. The outline view updates each batch that's merged back in. When it does this, the selection can be glitchy.

  3. Some projects under assigned groups remain blank. The object has been assigned the project, but the outline view hasn't refreshed the project properly. Presumably because the main thread is interrupted by the merges.

You can see these issues in the screencast I recorded:

http://screenr.com/Fk4

The Alternative

I could merge the changes from each operation into a managed object context running on a background thread. Them maybe I could send a message to the main thread to refresh all objects within the top level group that was changed.

That might get rid of problems 1 and 3 above, but I think 2 would still be an issue.

My Question

Is there a better way of doing this?

Before I start reworking how I do this (I've already changed how this works once) I want to know if there's a better way or there are any drawbacks to this approach I don't know about.

Thanks in advance for any suggestions on alternatives.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

守望孤独 2024-10-02 12:49:41

我目前正生活在冰冻之中。但我认为答案是并行我的 NSOperations 并减少将合并所需的时间降至最低。毫无疑问,我可以对数据模型进行很多改进,以使操作也更容易合并。

我最近尝试在后台线程上实现合并,但很难使其工作。我想这将是我重新审视的事情。

I'm currently living with the freeze. But I think the answer is to parallel up my NSOperations and just reduce the time taken to make the merge to the minimum possible. There are doubtless lots of improvements I can make to the data model to make the operations much easier to merge in too.

I tried to implement a merge on background thread recently, but struggled to make it work. It'll be something I revisit, I think.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文