Reputation: 4127
I have a NSTabView
with several tab view items. When a user hits a certain button, the tabview changes to one of these items to display things returned from a website api. I tried to create an intermediate tab view item to tell the user that it is fetching the data and then once fetched it will display it.
[tabView selectTabViewItemAtIndex:0]; // This is the intermediate tab
/*
Fetching
data from
the api
here
*/
[tabView selectTabViewItemAtIndex:1]; // Displaying the data tab
But the first tab never gets shown, only the last one. I wondered if it was just getting the data very quickly and didn't have time to show it, but I set a breakpoint halfway through but it still hadn't been changed. It only seems to be getting changed at the end, weird.
Any ideas?
Update:
Thanks for the answer, fixed it as follows
[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
});
Upvotes: 1
Views: 947
Reputation: 4758
Does the API that fetches data operate synchronously? I'm willing to bet that it does.
The user interface is only going to update at the end of the run loop running on the main thread. If the API that handles the fetching runs in the same thread then things are going to end up working like this:
You probably need to run your data fetch routines in a background thread. Then when it returns data, tell the NSTabView to select tab index 1. Since the data fetch occurs in the background, the run loop will have a chance to update the UI more than once which should result in tab index 0 becoming visible (for a short while anyway).
You can run the data fetch in the background using a couple of different methods. The obvious ones are to use Grand Central Dispatch or you could also use the "performSelectorInBackground:" series of methods that are part of the NSObject protocol.
Also you should ALWAYS be very careful about what operations you perform on the main thread. Fetching data from a website could take a while. If you run that operation synchronously on the main thread then the user interface will be completely non responsive while you wait for that data fetch to complete. Apple talks about this in their documentation on multithreading.. Definitely worth a read. That and Grand Central Dispatch - it makes multithreading much much easier.
Upvotes: 2