代码之家  ›  专栏  ›  技术社区  ›  John Gallagher

我应该为UI操作使用后台线程吗?

  •  2
  • John Gallagher  · 技术社区  · 14 年前

    背景

    • 我有一个 NSOutlineView 显示培训组实体。

    • 这个 大纲视图 NSTreeController IsTrained == 0

    • 每个培训小组可以分配到一个项目。

    • 每个培训组都有许多培训尝试,显示在该文件上工作的时间。

    • 当培训小组被分配到一个项目时 IsTrained YES

    • “指定给项目”时,所有子代也将指定给该项目及其子代 属性设置为

    • 项目列绑定到 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
    

    而内观只能看到:

    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
    

    Users                      nil                  NO
      John                     nil                  NO              
        Documents              nil                  NO
          New Project          nil                  NO
            StartingUp.doc     nil                  NO
    

    代码

    培训组.m

    -(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个进度条

    • 在单独上下文中的后台线程上运行项目分配。
    • 在项目分配完成之前,模式表会阻止任何进一步的活动。

    好的

    • 应用程序保持响应。

    • 在当前分配完成之前,用户不能执行任何操作。

    2非模态旋转器

    方法

    • 完成后使用标准核心数据合并到主上下文中。
    • 在训练组旁边显示进度微调器,表示它很忙。
    • 完成分配后,培训组将从视图中消失。

    坏的

    • 在测试中,我看到当背景上下文合并到主上下文中时,最多冻结3秒。
    • 撤消将很难实现。

    3隐藏

    方法

    • 除此之外,培训组在分配时被删除,并设置为“进行中”,直到分配完成。

    • 仍然大量冻结合并回主上下文。

    4提高绩效

    • 保持代码在主线程上运行。
    • 提高性能,这样即使有数千个条目,视图最多也只能冻结半秒

    好的

    • 撤消仍然很容易。

    坏的

    • 据我所知,与苹果的建议相反,密集型处理不应该在主线程上完成
    • 我能表演得足够好吗?未知。

    我的问题

    据我所知,上面的选项都不理想。

    2还有其他选择吗?

    1 回复  |  直到 14 年前
        1
  •  1
  •   jrtc27    14 年前
    1. 我会更新一个背景线程(2号)
    2. 您可以始终禁用窗口部分的用户输入,并显示加载消息。