Tony in IOS | 08/08/2013 IOS notifies the Observer that the tuned function does not necessarily run on the main thread
A small detail that was found when fixing the bug today is recorded.
Problem description
The thing is this: I registered a notification in a view (UITableView), and when I receive this notification, I reread the data and call it [tableView reloadData] . However, the view sometimes refreshes after the display of the wrong content, and then re-switch the view is normal.
The code is as follows:
| 12345678910111213141516 |
//a View registering notifications when initializing- (void)viewdidload { //... [[nsnotificationcenter defaultcenter] addobserver: Self selector: @selector(reloadfavdbdata:) name:@ "Refreshmyfavortiedata" object : nil]; }the tuned function after receiving the notification- (void)reloadfavdbdata:(nsnotification*)sender { [_dataarray release]; _dataarray = [musiccollecteddataoperate getsongcollectedinfowithkeyword: Nil ]; //re-fetch data [tableView reloaddata]; }//The caller runs in a thread and calls the notification to tell a view to refresh the data[[nsnotificationcenter defaultcenter] postnotificationname:@ " Refreshmyfavortiedata " object: Nil"; |
Analysis & Resolution
After some debugging, after the function Reloadfavdbdata hit break point unexpectedly discovered, it is not in the main thread run! And we do the UI-related operations here- [tableView reloadData] the UI refresh operation on the non-main thread, causing the problem of displaying the exception.
The solution is also very simple, in the function of the switch to the main thread and then do the operation on the line.
| 123456789101112131415 |
- (void)reloadfavdbdata:(nsnotification*)sender { @synchronized(self) //Ensure thread safety { ///Get new data, note the difference between this and the above code, because the acquisition of data operation takes a relatively long time, //The original implementation may cause TableView to crash when acquiring data nsarray *tmparray = [musiccollecteddataoperate GETSONGCOLLECTEDINFOWITHK Eyword: nil]; //switch to main thread dispatch_async(dispatch_get_main_queue(), ^{ [_dataarray release]; _dataarray = [tmparray retain]; [self. Refreshtableview. Mytableview reloaddata]; }); }} |
Why?
The result of the test is not complete enough. Turned over the official document, in the Nsnotificationcenter section to see such a passage:
In a multithreaded application, notifications is always delivered in the thread in which the notification is posted, whi CH may isn't being the same thread in which an observer registered itself.
In a multithreaded program, notifications are always called in the thread that sends the notifier (delivered, can you understand that?). , in combination with the situation described above, I understand that the tuned function that notifies the observer is always running in the thread that sent the notifier, as shown in:
This conclusion tells us that the tuned function of the notification does not necessarily run in the main thread, and if a UI-related operation is required, it needs to be manually switched to the main thread.
Have time to try to see the implementation of the principle of notification, should have a more thorough understanding.
IOS notifies the Observer that the tuned function does not necessarily run on the main thread