I am interested in knowing whether I can expect the observing object's method to be pushed onto the stack before the posting object's method has been completed and removed.
The short answer is yes... "Regular notification centers deliver notifications on the thread in which the notification was posted. Distributed notification centers deliver notifications on the main thread".
However, Apple has docs on this very subject that you may find helpful, and from which the above quote was pulled:
Notification Programming Topics: Delivering Notifications to Particular Threads
Just bothered to look it up myself, shameful:
From the class reference: NSNotificationCenter posts all notifications synchronously
Also, if you prefer, you can use NSNotificationQueue to post notifications asynchronously
Related
I have been doing a great deal of work using Notifications in few of my apps, at first they gave me random crashes but then I learned about the best way to use NSNotifications and here are a few best practices that I learnt.
---remove the observe's when they are of no use.
---remove the observer's before they are deallocated, leads to random crashes.
---Do not add two observers methods in the same class for the same notification.
If I am wrong or If I miss anything feel free to add up. What I want now is when I post a notification can I see the list of observer's waiting to receive my notificaton and can I selectively post to a set of observer's by missing out some intentionally?.
I also saw this Thread that is quite similar. I am creating a new thread because I want to dig up more with Notifications. I expect good contributions.
Just wondering, does anyone have experience with activating large amounts of NSNotification observers at a time?
What is the overhead of an observer? Is it reasonable to run, say, 50 or 100 or more observers at a time?
I have an application that displays a scrolling list of media from database and I want to implement NSNotificationCenter as a scalable method of listening for individual pieces of media and allocating them to the proper UIViews
Cheers,
Doug
Notification does not have overheads if they are processed in background. If you process NSNotification in one single thread then any one of the observers can mishandle it which would lead to a blocking thread. If this thread happens to be the main thread (in your case it is ) then app will freeze .
It depends upon the way notification is handled. Sending notification is not an overhead they are just 50 -100 method calls just like any other methods. (I have 5000 methods in my app). The issue is thw way it is handled. If each observer blocks the notification for a long time then nothing can be done. I will suggest using NSNotification queues instead NSNotification Queue
If time permits I would also suggest to refer reading article on Objects Communication by apple.
I'm going to take J2theC's advice on this one..
I'm currently shifting the design pattern to use delegate methods to prevent any freezing..
Thanks for the feedback!
These notices are being logged on behalf of my app (which implements GKSessionDelegate), and I could really make use of these events to help users with connection difficulties. Is there any way I can detect them? There aren't any public instance methods for the delegate that directly refer to these events.
I'm hoping there's some sort of generic event catch-all for delegates that I could rig up.
GKSessionTester[79766:307] BTM: attaching to BTServer
GKSessionTester[79766:307] <<< Session >>> +[GKBluetoothSupport _determineBluetoothStatus]: BT not available - try again later.
GKSessionTester[79766:307] BTM: posting notification BluetoothAvailabilityChangedNotification
As Gonzalo mentions in the comments, it looks like a notification is being posted with the name BluetoothAvailabilityChangedNotification.
Cocoa's notifications system is based around NSNotificationCenter, which maintains a list of observers and forwards notifications based on names, which are simply NSStrings. It is very likely that you can receive notifications if you call:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(bluetoothAvailabilityChanged:)
name:#"BluetoothAvailabilityChangedNotification"
object:nil];
And implement the method:
- (void)bluetoothAvailabilityChanged:(NSNotification *)notification
{
// maybe [notification userInfo] has some useful info...
}
You might not receive any notifications if GameKit is using a separate notification center object.
Does this count as private API? I would say it's no worse than parsing your console output. You are not calling methods on undocumented classes, you are passively observing notifications posted with a given name.
Of course, Apple's opinion is the only one that matters. If I were in your shoes, I would make sure that:
your app functions correctly if the notification is never posted (because a future iOS might not post it, or you might have to remove the code and resubmit without it);
your app makes no assumptions about the NSNotification's object or contents of its userInfo dictionary (because whatever they contain today might change in the future).
Alternatively, you could figure out a way to intercept your own app's STDOUT and STDERR (any solution that works on generic UNIX may work on iOS) and watch the text for relevant log messages.
Is there a way to know if an object is already registered as an observer for a particular notification?
In my implementation I have to add and remove the observers on the fly. For some reason, there is a random issue where the listener is receiving twice the same notification. I know I have to review my coding but It will be easier to fix for me if I could know this info.
Thanks.
No. There is no way to query this information. If you need it, you need to keep track of that yourself.
You might want to look into NSNotificationQueue. Here's the overview from Apple. It sounds like this could help you stop receiving duplicate notifications:
NSNotificationQueue objects (or simply
notification queues) act as buffers
for notification centers (instances of
NSNotificationCenter). Whereas a
notification center distributes
notifications when posted,
notifications placed into the queue
can be delayed until the end of the
current pass through the run loop or
until the run loop is idle. Duplicate
notifications can also be coalesced so
that only one notification is sent
although multiple notifications are
posted. A notification queue maintains
notifications (instances of
NSNotification) generally in a first
in first out (FIFO) order. When a
notification rises to the front of the
queue, the queue posts it to the
notification center, which in turn
dispatches the notification to all
objects registered as observers.
Every thread has a default
notification queue, which is
associated with the default
notification center for the task. You
can create your own notification
queues and have multiple queues per
center and thread.
I want to know how long does it take from posting a notification to getting the notification.
The reason is that I want to find out if the observer pattern is suitable for me. I don't want that another view controller can change the value before the notification has been sent and processed. I'm afraid that another process (thread?) is faster and the value will be overwritten when it shouldn't.
A notification center delivers messages synchronously, which means that the postNotification: method does not return until all objects registered to receive the notification have processed the notification. In other words, you can think of it as taking no time between posting a notification and receiving the notification.
There are a few extra things you'll need to be aware of:
Notifications are received on the same thread in which they are posted. If you move a notification over to the main thread using performSelectorOnMainThread:withObject:waitUntilDone:, you can break the synchronous behavior if waitUntilDone is set to NO. If waitUntilDone is set to YES, the thread passing the notification will block until the main thread has finished performing the specified action.
There is no guarantee of the order in which a notification will be received by its observers. If a single notification has multiple observers, don't rely on those observers receiving the notification in any particular order.
Given the above, and knowing which thread is posting notifications in your application and which thread needs to process them, you should be able to figure out whether the observer pattern will work for you.
you can use enqueueNotification for finer grained control over the processing of the notifications, but in the end I believe you can run into the same issue you have expressed concern about regardless of a NotificationCenter implementation or not