UI刷新,NSOutlineView reloadData和递归方法

时间:2011-09-28 15:52:24

标签: cocoa grand-central-dispatch nsoutlineview

我填充NSOutlineView递归读取目录。 读取目录及其子目录后,我刷新调用reloadData的大纲,如下所示:

-(void)readDir:(NSString*)path {
   dispatch_async(dispatch_get_main_queue(), ^{ \
      [outlineView reloadData];
   });

 //////////
 //// some internal stuff
 //////////

  NSArray* subs = [self getSubDirs:path];
  for (NSString* p in subs) {
      [self readDir:p];
  }
}

从调度内部调用上面的方法以使UI具有反应性

   - (void)startAll {
        dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
        dispatch_async(queue, ^{
           [self readDir:@"/"];
        });
   }

问题是有时dispatch_async(dispatch_get_main_queue(),...)在子目录正在读取时调用(它完全是异步的!)并且应用程序崩溃

如果我使用dispatch_sync(dispatch_get_main_queue(),...)(注意同步版本),轮廓总是正确绘制,但它非常非常慢,所以问题是:

如何重新安排代码尽可能快并等待dispatch_ [a] sync(dispatch_get_main_queue(),...)完成?

2 个答案:

答案 0 :(得分:3)

听起来问题是当some internal stuff在一个线程中执行时,您的模型处于不一致的状态,reloadData无法正确处理。

您是否在充分设置之前将目录条目添加到其父目录?

答案 1 :(得分:1)

到目前为止,但似乎更有意义的是这样写readDir:

-(void)readDir:(NSString*)path {
   //////////
   //// some internal stuff
   //////////

    NSArray* subs = [self getSubDirs:path];
    for (NSString* p in subs) {
        [self readDir:p];
        // now refresh outline with newly acquired info and current data
        dispatch_sync(dispatch_get_main_queue(), ^{ \
          [outlineView reloadData];
        });
    }
}