4

AFHTTPSessionManager GET:... does not perform it's blocks when dispatch group waits. dispatch_group_wait waits really "FOREVER". In my code @"all done" never happens.

How can I make it work?

(sorry. as I see, most people are interested to know the reason to use dispatch groups here. The reason is to perform requests in loop and wait the last response is got. I intentionally did not show my loop in code, because the loop does not affect that blocks are not being performed)

dispatch_group_t group = dispatch_group_create();

NSString *urlString = @"someURLForExampleReturnJSON";
dispatch_group_enter(group);
[self.sessionManager GET:urlString parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject)
 {
     NSLog(@"success block execution");
     dispatch_group_leave(group);
 } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
     NSLog(@"failure block execution");
     dispatch_group_leave(group);
 }];

dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"all done");
  • hmm i dont think this is what a dispatch_group is intended for (specifically like this), you should probably be using a dispatch_semaphore instead – Fonix Oct 20 '16 at 08:06
  • I am not able to understand what is the use of `dispatch_group` here ? can you please explain what you need here ? why you use `dispatch_group` ? – CodeChanger Oct 20 '16 at 09:09
  • better if you use dispatch_group_notify – Andrea Oct 20 '16 at 10:00

1 Answers1

2

First: You do not want to wait and and block the main thread.

Actual Problem: You are creating a deadlock. You can use group.notify:

Obj-C:

dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    NSLog(@"all done");
});

Swift 3:

group.notify(queue: DispatchQueue.main, execute: {
    print("all Done")
}) 

This does not make sense though, as you can archive the same result without dispatch groups, which I would highly recommend:

[self.sessionManager GET:urlString parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
     NSLog(@"all done");
 } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
     NSLog(@"failure block execution");
 }];

If you really want to wait, use this approach:

import Foundation

print("main start")

let group = DispatchGroup()
group.enter()
// put your heavy task on background queue
DispatchQueue.global(qos: .background).async { 
    print("background start")
    sleep(2) // do some long running task
    print("background stop")
    group.leave()
}

// wait on main queue
group.wait() 
print("go on")
shallowThought
  • 19,212
  • 9
  • 65
  • 112