You need what's called a 'Selector'.
I'd recommend using the synchronous calls still - but in a separate thread. The reason behind this is that despite being async, if you're transferring data in the current thread, you will still experience UI slowness issues. If you're using the global Network Activity Indicator, this is not an issue - but an indicator local to your app (or any other screen redraws) - will appear to be locked up.
Therefore, create a class called ImageDownloader (or somesuch), and place your synchronous download call in there, to grab your image data. As one of the members of your class, declare (in the interface):
SEL successSelector;
When you create this class (say you want to pass in a URL, and get back your image data, create an init function of the following form (that takes in a SEL), and call it using:
[ImageDownloader alloc] initWithSelector: @"http://url string" :self : @selector(yourFunction:)
]
Basically, you need to pass an object, and the method in that object, to call back when its done.
The 'initWithSelector' implementation looks like:
-(id) initWithSelector: (NSString*)url :(id)adelegate :(SEL) successSeletor {
self.url = url;
self.delegate = adelegate;
self.sel = successSelector;
}
(Note the colon after 'yourFunction' - you need a colon for each parameter your callback function has.
So the sig for yourFunction looks like:
-(void) yourFunction: (NSData*)imageData;
To call this from your ImageDownloader class (when the download is done), just call your selector using:
[delegate performSelector:sel withObject:imageData];
Enjoy!