gpt4 book ai didi

multithreading - 我应该在UI Action 中使用后台线程吗?

转载 作者:行者123 更新时间:2023-12-03 16:44:41 25 4
gpt4 key购买 nike

背景

  • 我有一个显示TrainingGroup实体的NSOutlineView
  • 每个TrainingGroup代表本地计算机上的一个文件夹。
  • NSOutlineView绑定(bind)到具有NSTreeController的获取谓词的IsTrained == 0
  • 每个TrainingGroup都可以分配给一个项目。
  • 每个TrainingGroup都有许多TrainingEntries,它们显示在该文件上工作的时间。
  • 将TrainingGroup分配给项目时,IsTrained设置为YES
  • 分配给项目时,所有后代也都分配给该项目,并且它们的IsTrained属性也设置为YES
  • 项目列绑定(bind)到projectTopLevel属性。

  • 示例

    整个树看起来像这样:
    Name                       Project              IsTrained
    Users nil NO
    John nil NO
    Documents nil NO
    Acme Project Acme Project YES
    Proposal.doc Acme Project YES
    12:32-12:33 Acme Project YES
    13:11-13:33 Acme Project YES
    ... etc
    Budget.xls Acme Project YES
    Big Co Project Big Co Project YES
    Deadlines.txt Big Co Project YES
    Spec.doc Big Co Project YES
    New Project nil NO
    StartingUp.doc nil NO
    Personal Stuff Personal YES
    MyTreehouse.doc Personal YES
    Movies nil NO
    Aliens.mov nil NO
    StepMom.mov nil NO

    而且NSOutlineView只会看到以下内容:
    Users                      nil                  NO
    John nil NO
    Documents nil NO
    New Project nil NO
    StartingUp.doc nil NO
    Movies nil NO
    Aliens.mov nil NO
    StepMom.mov nil NO

    如果您将电影分配给个人,则 View 现在将如下所示:
    Users                      nil                  NO
    John nil NO
    Documents nil NO
    New Project nil NO
    StartingUp.doc nil NO

    代码

    培训小组
    -(void)setProjectTopLevel:(JGProject *)projectToAssign {
    [self setProjectForSelf:projectToAssign];
    [self setProjectForChildren:projectToAssign];
    }

    -(void)setProjectForSelf:(JGProject *)projectToAssign {
    [self setProject:projectToAssign];
    }

    -(void)setProjectForChildren:(JGProject *)projectToAssign {
    for (TrainingGroup *thisTrainingGroup in [self descendants]) {
    [thisTrainingGroup setProject:projectToAssign];
    if(projectToAssign != nil) {
    [thisTrainingGroup setIsTrainedValue:YES];
    } else {
    [thisTrainingGroup setIsTrainedValue:NO];
    }
    // Other code updating rules.
    }
    }

    -(JGProject *)projectTopLevel {
    return [self project];
    }

    -(NSSet *)untrainedChildren {
    // Code that loops through all children returning those
    // whose isTrained is NO. Omitted for brevity.
    }

    问题

    如您在上面看到的,我目前正在主线程上运行所有项目分配代码。

    当每个文件夹下都有数百个时间条目时,我的应用程序将无响应。

    可能的解决方案

    1模态进度栏

    该方法
  • 在单独的上下文中的后台线程上运行项目分配。
  • 完成后,使用标准Core Data合并到主上下文中。
  • 模态表会阻止任何进一步的 Activity ,直到项目分配完成。

  • 善良
  • 用户可以立即获得正在发生的事情的反馈。
  • 该应用程序保持响应状态。

  • 坏人
  • 在当前分配完成之前,用户无法执行任何操作。

  • 2非模态微调器

    该方法
  • 在单独的上下文中的后台线程上运行项目分配。
  • 完成后,使用标准Core Data合并到主上下文中。
  • 与培训小组一起显示进度微调器,表明它很忙。
  • 完成分配后,训练组将从 View 中消失。

  • 善良
  • 用户可以在处理其最后一个 Action 时做其他事情
  • 该应用程序保持响应状态。金田见下文。

  • 坏人
  • 在测试中,当背景上下文合并到主上下文中时,我看到最多冻结了3秒。
  • 该 View 可能会在用户执行其他操作时更新,这可能很烦人。
  • 撤消将很难实现。

  • 3隐藏

    该方法
  • 上面,除了训练组是在分配时删除的,并且设置为“进行中”,直到分配完成。

  • 好和坏
  • 与上面相同,除了训练组的顺序仍然是可预测的。
  • 在合并回到主上下文中时仍然很大冻结。

  • 4提高性能

    该方法
  • 保持代码不变,在主线程上运行。
  • 提高性能,因此即使有成千上万的条目, View 也只能冻结最大半秒的

  • 善良
  • 应用程序保持响应状态。
  • 撤消仍然很容易。
  • 体系结构仍然很简单。

  • 坏人
  • 据我了解,不符合Apple的建议-不应在主线程
  • 上进行密集处理
  • 我能否获得足够好的性能?未知。

  • 我的问题

    据我所知,以上所有选项都不是理想的选择。

    1.哪个是最佳选择?

    2.还有其他选择吗?

    3.我的方法可以改进什么?

    最佳答案

  • 我将在后台线程(第2号)上更新
  • 您始终可以在窗口的各个部分上禁用用户输入,并显示加载消息。
  • 简单地说-遍历所有代码,并确保进行最少的调用,并且不要调用任何不必要的函数。您还可以在单​​独的线程上运行一些持久的操作,然后在操作完成时得到通知,因此您可以在操作继续进行时处理其他事情。
  • 关于multithreading - 我应该在UI Action 中使用后台线程吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3787058/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com