Objective-C fast enumeration and asynchronous server operations. Model help?
If I have a method c开发者_如何学编程alled "-uploadToServer:(Object *)objectToUpload", and a mutable array of several Objects, and I want to upload each object one after the other, how could I best handle this?
There are three important considerations:
- Don't want NSOperation because I don't want to deal with threading issues
- Need to wait for notification of task completion before continuing
- Server calls are asynchronous and non-blocking
Here is some code I already have:
for (Object *task in objectsToUpload) {
[self uploadToServer:task];
//need to wait to get notification that upload completed
}
-(void)uploadToServer:(Object *)objectToUpload {
//perform asynchronous server operation here
//either block callback or delegate to notify
//self that upload finished
}
Seeing the above, how do you think I should handle this?
Don't want NSOperation because I don't want to deal with threading issues
Honestly, I think this is your easiest option. The only other way is to do asynchronous IO and use the run loop.
With NSOperation, you'd need two different kinds of operation called e.g. UploadOperation
and NotifyOperation
: one to upload an object and one to send a notification to the main thread when everything is done.
Then you'd loop through thwe objects putting them all on an NSOperationQueue
in an UploadOperation
, each one dependent on the previous one (addDependency:
). Finally, you'd put the NotifyOperation
on the queue dependent on the last UploadOperation
.
The NotifyOperation
overrides main
as follows
-(void) main
{
[someObjectEgViewController performSelectorOnMainThread: @selector(finishedUpload)
withObject: nil
waitUntilDone: NO];
}
objectsToUpload
is an NSMutableArray
of tasks
-(void)uploadToServer{
//check if there is a task available
if (objectsToUpload.count > 0){
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
//get first task
id nextTask = [objectsToUpload objectAtIndex:0];
//do something
//complete async
dispatch_async(dispatch_get_main_queue(), ^(void) {
//remove completed task
[objectsToUpload removeObject:nextTask];
//complete async upload task, check or notify and or start the next task
BOOL shouldDoNextTask = [self check];
if (shouldDoNextTask){
[self uploadToServer];
}
});
});
}
}
I would suggest you do not need to wait for the task to complete. What you need is to respond to the task's completion.
NSURLConnection will provide a delegate with callback methods.
精彩评论