Does anyone know the best practice that how to start another new asynchronous method in the completion block of the first asynchronous communication?
I am testing the code to make a call NSFetchRequest(coz STACKMOB iOS SDK internally sync with server) asynchronously in completion callback of another asynchronous communication to Facebook. The execution of code suddenly terminates at the line of NSFetchRequest. I realized one of the reason why it doesn't work correctly. I guess that the completion block has been released from memory as soon as [managedObjectContext executeFetchRequest:fetchRequest error:&error] is invoked. but I don't know better solution to fix it. Thanks for any help.
The SDK uses:
- (void)queueRequest:(NSURLRequest *)request options:(SMRequestOptions *)options onSuccess:(SMFullResponseSuccessBlock)onSuccess onFailure:(SMFullResponseFailureBlock)onFailure
https://github.com/stackmob/stackmob-ios-sdk/blob/master/Classes/SMDataStore%2BProtected.m
I tried:
How do I wait for an asynchronously dispatched block to finish?
NSURLConnection sendAsynchronousRequest:queue:completionHandler: making multiple requests in a row?
:
- (IBAction)checkFacebookInfo:(id)sender
{
//completion block of facebook info
void(^onCompleteBlock)(NSDictionary*) = [[^(NSDictionary* userInfo)
{
NSManagedObjectContext *managedObjectContext = nil;
managedObjectContext = [[SingletonCoreData sharedManager] managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"User"];
//for STACKMOB, customized NSFetchRequest internally sync to the server. It is Asynchronous method.
NSArray *results = [managedObjectContext executeFetchRequest:fetchRequest error:&error];// failed
//Not reached here
//set userInfo to results here
} copy] autorelease];
//invoke onCompleteBlock after executing asynchronously, client(SMClient object for STACKMOB)
[client getLoggedInUserFacebookInfoWithOnSuccess:onCompleteBlock onFailure:^(NSError *error)
{
NSLog(@"No user found");
}];
}
Edited: I tried this written below, then it successfully works. But I feel it slow. I put a part of the code into 'dispatch_async' block. I am waiting for any other better solution.
- (IBAction)checkFacebookInfo:(id)sender
{
//completion block of facebook info
void(^onCompleteBlock)(NSDictionary*) = ^(NSDictionary* userInfo)
{
dispatch_queue_t gQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(gQueue, ^{
NSManagedObjectContext *managedObjectContext = nil;
managedObjectContext = [[SingletonCoreData sharedManager] managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"User"];
//for STACKMOB, customized NSFetchRequest internally sync to the server. It is Asynchronous method.
NSArray *results = [managedObjectContext executeFetchRequest:fetchRequest error:&error];// success
//set userInfo to results here
});
};
//invoke onCompleteBlock after executing asynchronously, client(SMClient object for STACKMOB)
[client getLoggedInUserFacebookInfoWithOnSuccess:onCompleteBlock onFailure:^(NSError *error)
{
NSLog(@"No user found");
}];
}