views:

852

answers:

2

I have an IPhone app that uses webservices to get data from a server. I'm putting each call to the webservice in a NSOperation subclass so that it can be threaded. My question is, what is the recommended way to pass back information from a completed NSOperation subclass. I'm currently sending a NSNotification at the end of my main method and any code that is waiting for the NSOperation to complete, subscribes to the notification. And then I will use the object part of NSNotificationWithName:Object: to pass information back from the operation.

I wasn't sure if there was a better way to do this. I have heard of Key Value Coding and then I could use Key Value Observing to detect when the the isFinished property for the operation is changed, but I'm not sure what the best practice is.

I'm also trying to ensure that my application is thread safe, which I assume wouldn't be an issue as long as a my notification was sent out at the end of the main method thus the object in the notification would no longer be used in the thread since it will end.

Finally, I am calling the notification like so:

[[NSNotificationCenter defaultCenter] performSelectorOnMainThread:@selector(postNotification:) withObject:[NSNotification notificationWithName:@"notificationName" object:dataObject] waitUntilDone:NO];
+1  A: 

It depends on your application. How many of the operations do you expect to run concurrently? What are you doing with the result? Are results aggregated or do they need to display in the UI immediately?

Sending notifications on the main thread is fairly heavyweight. Depending on what you're doing with the result, you could choke up your UI. From a design perspective, are the objects that you would be sending from the notification something that the observing class should know about? It may make more sense to make changes to your model objects from the operation and have a controller object observe those changes instead.

You could use Key Value Observing but you must be careful. The observer observes in the same thread that the change occurs on, so you should not make UI changes directly when observing isFinished.

If the object is only owned and used by the operation, then yes, it should be safe to send at the end of main. It will be retained by the notification.

orque
+4  A: 

I've personally done this in two ways. Both worked quite well.

First Way

You can have a function that returns the "output", and you call that function after the operation has finished. You can observe the key isFinished on the NSOperation object, or use -[NSOperationQueue waitUntilAllOperationsAreFinished] to determine when the operation is finished.

Second Way

You can use a delegate or target/action from the NSOperation. Just make sure that when you call the delegate function, or trigger the target/action, you do so on the main thread by using -[NSObject performSelectorOnMainThread:withObject:waitUntilDone:]

Tom Dalling