I am using GCD in my app to fetch lot of images and data in the background queue and when I present uiimagepickercontroller it takes more time to show the camera preview. After googling around, I found that many have faced this issue with iOS 7 and here is one more post that made some sense to me. ( iOS 7 UIImagePickerController Camera No Image ). The solution was to stop the background threads and then present the picker controller. But I am really stumped and don't know how to stop or pause the background threads, present the picker controller and then resume/start the background thread. Can someone please help me with this.
Here is how I am doing my background fetching of images and data in my networking class (like everyone else). My serial queue is initialized like this.
sharedInstance.serialQueue = dispatch_queue_create("user-detail-queue", DISPATCH_QUEUE_CONCURRENT);
And the code to fetch things in the background is like this.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSString *myUserID = [JNKeychain loadValueForKey:@"userID"];
NSString *sessionToken = [JNKeychain loadValueForKey:@"sessionToken"];
if(sessionToken && myUserID)
{
dispatch_async([BGNetworkAPI sharedInstance].serialQueue, ^{
id object = [[BGNetworkAPI sharedInstance].userCache objectForKey:myUserID];
if(object)
{
NSDictionary *cachedResponseDictionary = (NSDictionary *)object;
BGUser *user = [BGUser createUserWithResponseDictionary:cachedResponseDictionary];
if(block)
{
block(user, nil);
}
}
else
{
[[BGUserManagementClient sharedClient] fetchUserDetailsWithUserId:myUserID withSessionToken:sessionToken withSuccessBlock:^(AFHTTPRequestOperation *operation, id responseObject)
{
//NSLog(@"The response object of my user object is %@",responseObject);
[[BGNetworkAPI sharedInstance].userCache setObject:responseObject forKey:myUserID];
NSDictionary *responseDictionary = (NSDictionary *)responseObject;
BGUser *user = [BGUser createUserWithResponseDictionary:responseDictionary];
if(block)
{
block(user,nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(@"The error while fetching the user details is %@", operation.responseObject);
if(block)
{
block(nil, error);
}
}];
}
}
});
With the code above you are not doing the fetching in the backgroud as dispatch_get_main_queue()
gives you the queue the interface is running on. To perform a background fetch you have to open another queue with dispatch_queue_create("image_queue", NULL)
.
When the backgroud fetch is finished and you want to do something with the UI you have to do this in the main queue.
dispatch_async(dispatch_get_main_queue(),^{
if(block) {
block(user,nil)
}
});
After playing around with the code, I figured out the problem. In all the places where I am doing background fetch, I was sending the completion block just like that. When I changed the returning of the completion block in the main block, it started to work properly. Thanks a lot to @HackingOther to point out my mistake.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.