Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
549 views
in Technique[技术] by (71.8m points)

iphone - is it ok to use of a notification to communication back to the main thread of an IOS app? (cf performSelectorOnMainThread)

Is it ok to use of a notification to communication back to the main thread of an IOS app? (cf performSelectorOnMainThread). That is, there are are there any gottcha's for this purpose?

Background

  • want to call back to main UI thread from a background thread (e.g. performSelectorInBackground)
  • could use performSelectorOnMainThread to communicate back, but wondering if it is OK to use a notification?

For example

 [[NSNotificationCenter defaultCenter] postNotificationName:@"ModelChanged" object:self];
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Actually there is a gottcha; you'll crash randomly! That has been my experience. This has to do with the fact that the object receiving the notification does so on the same thread as the notification's sender.

From the Apple iOS Documentation on Notification Centers:

In a multithreaded application, notifications are always delivered in the thread in which the notification was posted, which may not be the same thread in which an observer registered itself.

This will inevitably cause you headaches.

If the notification is being received by something on the main thread, I've found that popping into the main thread from the background thread to issue a notification is the safest way to go about this. It is quite simple to do:

//Call this to post a notification and are on a background thread      
- (void) postmyNotification{
  [self performSelectorOnMainThread:@selector(helperMethod:) withObject:Nil waitUntilDone:NO];
}

//Do not call this directly if you are running on a background thread.
- (void) helperMethod{
  [[NSNotificationCenter defaultCenter] postNotificationName:@"SOMENAME" object:self];
}

Unfortunately this introduces a subtle coupling between the sender and receiver in that you are modifying the sender to accommodate the receiver.

An even better solution, as XJones points out, is to have the sender send out the notification on whatever thread it decides to, and then to make the listener responsible for using the proper thread to perform whatever action it needs to.

Hope that was helpful.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...