在一个方法中两次更改nstabview项目

时间:2011-10-21 15:45:24

标签: objective-c xcode macos cocoa

我有一个NSTabView,其中包含多个标签视图项。当用户点击某个按钮时,tabview会切换到其中一个项目以显示从网站api返回的内容。我尝试创建一个中间选项卡视图项,告诉用户它正在获取数据,然后一旦获取它将显示它。

[tabView selectTabViewItemAtIndex:0]; // This is the intermediate tab
/* 
   Fetching 
   data from
   the api
   here
*/
[tabView selectTabViewItemAtIndex:1]; // Displaying the data tab

但第一个标签永远不会显示,只显示最后一个标签。我想知道它是否只是非常快速地获取数据并且没有时间来显示它,但是我设置了一个断点,但它仍然没有被改变。它最近似乎只是变了,很奇怪。

有什么想法吗?

更新

感谢您的回答,修复如下

[tabView selectTabViewItemAtIndex:0]; // This is the intermediate tab

dispatch_queue_t queue = dispatch_queue_create("com.mycompany.queue", 0);
dispatch_async(queue, ^{
    /* 
       Fetching 
       data from
       the api
       here
    */
    [tabView selectTabViewItemAtIndex:1]; // Displaying the data tab
});

1 个答案:

答案 0 :(得分:2)

获取数据的API是否同步运行?我愿意打赌它确实如此。

用户界面仅在主线程上运行的运行循环结束时更新。如果处理提取的API在同一个线程中运行,那么事情最终会像这样工作:

  1. 开始运行循环
  2. 您选择标签索引0
  3. 您获取数据。
  4. 您选择标签索引1
  5. UI更新,显示标签索引1。
  6. 您可能需要在后台线程中运行数据提取例程。然后当它返回数据时,告诉NSTabView选择选项卡索引1.由于数据提取发生在后台,运行循环将有机会多次更新UI,这应该导致选项卡索引0变得可见(对于无论如何都是短暂的。)

    您可以使用几种不同的方法在后台运行数据提取。显而易见的是使用Grand Central Dispatch,或者您也可以使用属于NSObject协议的“performSelectorInBackground:”系列方法。

    此外,您应该始终非常小心您在主线程上执行的操作。从网站获取数据可能需要一段时间。如果在主线程上同步运行该操作,则在等待数据提取完成时,用户界面将完全无响应。 Apple在他们关于多线程的文档中讨论了这一点。绝对值得一读。那和Grand Central Dispatch - 它使多线程变得容易得多。