tags:

views:

2911

answers:

5

I'm fairly new to Objective-C and I can't figure out how to wait in a non-blocking manner. I have an object that is being populated asynchronously and I need to wait on it before I can proceed in another method. Right now I am using the sleep function, but this blocks the whole app and myObject never gets loaded.

while (!myObject)
{
    sleep(1);
}
return myObject;

EDIT: This code snippet is from a method that may be called before myObject has been loaded. In this case I actually do want to block in this method, but my code blocks everything including myObject from being loaded.

A: 

Sounds like you're looking for the observer pattern. Apple calls it "notification".

John M
Not really what I'm looking for. I don't want to be notified, I want *this* thread to be blocked until myObject is loaded, but my code blocks myObject from being loaded at all.
Stefan Moser
+4  A: 

If you can, give the class a myObjectLoaded: method to be called when the object in question is loaded. Otherwise, the the most idiomatic equivalent of what you wrote above is to create a timer that keeps checking for myObject and does something once it finds it.

If you really needed to do it in the middle of a method for some reason, you'd have to create a loop that keeps running the runloop. It's the lack of a runloop that causes your app to block.

Chuck
A: 

Assuming you have some background NSThread performing this population operation, you might like The NSObject method performSelector:onThread:withObject:waitUntilDone

Adam Wright
A: 

That's because you are stopping the main thread waiting for your object to be loaded. Don't do that, because the main thread is the thread that drives the UI, and waits for user input. If you block the main thread you block the application user interface.

If you want the main thread to do something when the object is loaded, then create a method myObjectLoaded: and call from your loading threads:

[myObjectController performSelectorOnMainThread:@selector(myObjectLoaded:) 
                                     withObject:myObject 
                                  waitUntilDone:NO];

where myObjectController can be any object even myObject itself.

IlDan
+1  A: 

NSNotification should solve the problem.

http://developer.apple.com/documentation/Cocoa/Conceptual/Notifications/Introduction/introNotifications.html

Instead of waiting on on object, have this object register for notifications coming from your other object (say Publisher) which populates the data asynchronously. One this Publisher object finishes, have it post an NSNotification, which will then be automatically picked up by your waiting object. This would eliminate waiting too.

Nocturne