ios - Waiting for multiple blocks to finish -
i have methods retrieve object information internet:
- (void)downloadappinfo:(void(^)())success failure:(void(^)(nserror *error))failure; - (void)getavailablehosts:(void(^)())success failure:(void(^)(nserror *error))failure; - (void)getavailableservices:(void(^)())success failure:(void(^)(nserror *error))failure; - (void)getavailableactions:(void(^)())success failure:(void(^)(nserror *error))failure;
the downloaded stuff gets stored in object properties, why success functions return nothing.
now, want have 1 method this:
- (void)synceverything:(void(^)())success failure:(void(^)(nserror *error))failure;
which nothing else calling methods above, , returning after every single method has performed success or failure block.
how can this?
hint: aware cascading methods calls in each others success block work. neither 'clean' nor helpful when later implementations include further methods.
edit:
i tried running each of calls in nsoperation
, adding nsoperations
nsoperationqueue
followed "completion operation" depends on every 1 of preceding operations.
this won't work. since operations considered completed before respective success/failure blocks return.
i aware, put each of calls in subclassed nsoperation, can myself decide when fire completion block. sounds overkill, or way go?
this did:
nsoperation *completionoperation = [nsoperation new]; completionoperation.completionblock = sucess; // defined somewhere else nsoperationqueue *queue = [nsoperationqueue new]; for(anappliance *appliance in _mutappliances) { nslog(@"add app"); nsoperation *operation = [nsoperation new]; operation.completionblock = ^{ [self downloadhostsforappliancewithname:appliance.networksettings.name success:^ { nslog(@"downloaded"); //sucess(); } failure:^(nserror *error) { //failure(error); }]; }; [completionoperation adddependency:operation]; [queue addoperation:operation]; } [queue addoperation:completionoperation];
edit:
now tried dispatch_group
thing. not me wether doing right way:
for(appliance *appliance in _mutappliances) dispatch_group_async(group, dispatch_get_global_queue(dispatch_queue_priority_default, 0), ^ { nslog(@"block start"); [appliance downloadappinfo:^ { nslog(@"block success"); } failure:^(nserror *error) { nslog(@"block end"); }]; nslog(@"block end"); }); dispatch_group_notify(group, dispatch_get_global_queue(dispatch_queue_priority_default, 0), ^ { nslog(@"final block"); sucess(); });
unfortunately, not working way. "block success" shows @ end.
you there, problem methods asynchronous, need synchronization step. try following fix:
for(appliance *appliance in _mutappliances) { dispatch_group_async( group, dispatch_get_global_queue(dispatch_queue_priority_default, 0), ^{ dispatch_semaphore_t sem = dispatch_semaphore_create( 0 ); nslog(@"block start"); [appliance downloadappinfo:^{ nslog(@"block success"); dispatch_semaphore_signal(sem); } failure:^(nserror *error){ nslog(@"block failure"); dispatch_semaphore_signal(sem); }]; dispatch_semaphore_wait(sem, dispatch_time_forever); nslog(@"block end"); }); dispatch_group_notify( group, dispatch_get_global_queue(dispatch_queue_priority_default, 0),^{ nslog(@"final block"); success(); }); }
Comments
Post a Comment