NSNotification observer Overhead - iphone

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!

Related

Correct way to poll a webservice in an IPhone app

I am trying to determine the best strategy to poll a webservice once a minute, parse the xml returned and then update an object stored in a shared instance. This process needs to run in a separate thread, and will continue as long as the app is running.
It seems that I could put all the code to call the webservice and parse the xml into an NSOperation and add that NSOperation to an NSOperationQueue stored in the app delegate as soon as the app launches.
Is it a correct approach to use an NSTimer inside the main method of the NSOperation so that the operation will loop once a minute, indefinitely? In that scenario the NSOperation would never actually return - this seems what I want but I am not sure if this is the right way to think about it.
The problem I am trying to solve is of course extremely common, so I am trying to figure out the correct way to implement it. Any advice greatly appreciated.
The real correct way to do it is to use push notifications. If any of your users have cell plans with limited data or data charged based on usage, they will thank you for it.
But if you insist on polling, you may as well use the NSTimer directly rather than messing with a timer inside an NSOperation. This will run on the main thread, but you could have the timer callback use performSelectorInBackground:withObject: to do processing in the background. Or you could just skip the timer altogether and run the whole polling sequence on a separate NSThread, and use sleepForTimeInterval: to delay between polls.
I would highly recommend you take a look at ASIHTTPRequest. What an amazing little class, and really well documented.
Edit:
Take a look at this answer for what seems to be the optimal solution.
one approach: create a thread and use a run loop, updating or idling as appropriate. then you can perform the request from the secondary thread and post it to the rest of the app after it's been parsed/prepped.
this way offers more control over pause/resume/delays/timing, and you can easily control the number of active requests (which should be exactly zero or one).
I wouldn't use NSTimer for this problem/design. I would create NSThread from the AppDelegate when the application starts. I would lower the priority of this thread. Inside the NSThread main method is basically a loop.
-(void)main {
while(true) {
// get raw data from url
// hash the result
// compare the hash to the last time
if (currentHash != lastHash) {
// post a notification to default center with the new data
lastHash = currentHash;
}
// sleep the thread sleepForTimeInterval
}
}
Your Model object would subscribe to the notification from the thread and parse the new data and updates ivars. Your View object would listen to the Model using KVO and display any updates/changes.

Running C code in an Objective C (Cocoa) Thread (for iOS)

First of all, I am a a very new Objective C/Cocoa iOS Developer but I've written C/C++ applications before.
So I managed to run the Rabbitmq-c (http://hg.rabbitmq.com/rabbitmq-c/) client inside my iPhone App, and I can connect to Rabbitmq directly from my app and even consume a queue item. So all's good.
Now my problem is, my iPhone app needs to use the rabbitmq-c library to poll for incoming messages in from the server. Probably there will be, an almost infinite while loop.
Do I have to take this to a new thread? Ideally, I want to wrap the rabbitmq-c class as an Async objective C class and use NSNotification (or something similar) to notify my UI. I'm a bit leery of creating a new thread, as I read about stuffs like Runloop etc can solve a lot of problems without using an extra thread.
What is the best way for me to go about this? Any examples of code or directions would be helpful. Please remember, I am not dealing with an Objective C code/Coca rabbitmq library here, I'm using C code inside my iPhone app.
Thanks
Subrat
don't block the main thread with your server polling.
since the operation never ends, create your own thread and run loop for this server polling. you can potentially use the run loop (each thread has one) instead of the infinite while. the alternatives involve regularly spawning threads. it's easiest to just use one thread for this.
once you have an update, post the notification (if you choose NSNotification) from the main thread -- UIKit is meant to operate from the main thread only.
for samples, i'd begin with samples related to NSRunLoop and CFRunLoop.
good luck
You can also create custom delegates for updating the UI, or the stuff related to UIKit.
Notifications might be a little easier to code and offer the advantage that multiple objects can observe one notification. With delegates, such a thing cannot be done without modifying the delegating object (and is unusual).
Some advantages of delegating:
The connection between delegating object and delegate is made clearer, especially if implementing the delegate is mandatory.
If more than one type of message has to be passed from delegatee to delegate, delegating can make this clearer by specifying one delegate method per message.
Or other way is to write method to receive messages. This method can have infinite loop.
Later you can put this method in background thread like this.
[self performSelectorInBackground:#selector(receiveMessages) withObject:nil];

KVO rocks. Now how do I use it asynchronously?

I am sold on KVO but if used in the obvious way it is synchronous. I would like to use it in a situation where I am firing off many KVO messages in rapid succession and it is causing my app to grind to a halt as the KVO messages are handled. Can someone suggest an approach - perhaps using NSOperation or NSThread - that will work here?
My goal is to retain the decoupled, flexibility of KVO if possible.
KVO is inherently single threaded in that the KVO notifications will be delivered on the same thread as the change.
Of course, UIKit and Cocoa both really only want you to be diddling UI elements on the main thread.
Thus, if you are doing asynchronous operations, you are most likely using threads and, if so, already have a synchronization issue in that you need to get the notifs from some thread to the main thread.
And therein lies the key. Instead of blindly forwarding each change notification as it comes in, you can coalesce the change notifications before passing them on to the main thread.
There are a variety of means via which you can do this. The specific solution is going to be quite unique to your application, most likely.
Personally, I try to avoid coalesce-and-forward of fine grained operations. I find it far simpler to tell the main thread that a particular sub-graph of objects have changed. More likely than not, the drawing code that will then make the changes visible to the user is going to need to redraw related state and, thus, related changes will be automatically reflected.
The key, as you have surmised, is to throttle the notifications so you don't bog down app responsiveness (or destroy the devices battery life).
Use the Receptionist Pattern as recommended by Apple https://developer.apple.com/library/ios/documentation/general/conceptual/CocoaEncyclopedia/ReceptionistPattern/ReceptionistPattern.html
Check out NSNotification. It's not quite the same thing, but you can fire off notifications on background threads (with a little bit of research and work). You can maintain the nice decoupling and fire-and-forget behavior.

Best practices for Singletons and Notifications on the iPhone

Just to give background for my situation, I have a manager singleton that pulls data from a webserver and provides access to the downloaded data. I have several types of views that will consume this data, but only one view at any time will need to receive events.
I was just wondering what people prefer to use when they need to get events from a singleton. Do you use NSNotificationCenter, Target/Action, or delegate?
Thanks for any help.
Are you really, really sure only one view needs to receive events? For instance, you don't have a master view that would need access to the same update that a subview was notified about?
If you truly have only one view controller needing updates at a time ever, I might use a delegate approach. Here's something to consider - what happens if you are in the middle of receiving an update and the user change screens... is that OK? would you cancel the request?
Anything more than one, or if that in-flight changing delegate scenario has issues, then you may well be better off with a notification that anyone can hook into. It's best to keep the notification light with some kind of reference to the change and have the receiver have to look up the altered data.
If there are going to be a large number of events, then you want to stay away from NSNotifications.
For the least amount of overhead I would go with the delegate pattern, although I don't think that target/action has much more overhead than delegates.
Try your favorite way and if there is a problem profile or try a different approach.
I usually start with the easiest to get implemented. For example I once tried to use notifications for some interface code I had written years ago but with 30-60 updates/second the whole interface bogged down unacceptably so I went with delegates which fixed the problem.

Online play possibilities for iPhone game?

How would you guys go about creating online play capabilities for an iPhone game? Obviously, one could poll the server every so often, but is this realistic given the capabilities of the device? Assume you're polling the server every second or two and retrieving 100 bytes of data... Is it possible to retrieve the data in the background while gameplay continues or is it going to be held up by the server poll?
Thanks in advance,
BCH
You need to make a multithreaded application. Then you can have a background thread polling the server (or better, making asynchronous requests on it.
Have a look at the NSOperation and NSOperationQueue classes. You'll make each background task be represented by an instance of an NSOperation class. This class takes care of starting the operations, making sure that they are run in the appropriate order, and accounting for any priorities that you set.
The most common way to use NSOperation is to write a custom subclass and override the method, main. The main method gets called to perform the operation when the NSOperationQueue schedules it to run.
If you don't want the overhead of subclassing, take a look at the NSInvocationOperation class. This is a concrete subclass of NSOperation that makes it easy to attach an operation to an existing method. NSInvocationOperation objects can be added to an NSOperationQueue (just like NSOperations), so that you get multi-threading without having to subclass.
You can do asynchromous requests. But you are asking a really, really hard question here. Just want to make sure you know that.
Take a look at the WiTap example (in xcode do a full text search for witap). It uses NSStreams to get asynchronous behavior without you having to resort to managing your own threads or poll.
Use OpenFeint.. It allows you to develop Over the internet worldwide non real time turn based multiplayer games easily..
I'm not sure if GameCenter now supports similar functions.