2016-04-24 9 views
5

Ich muss warten, bis mehrere AFNetworking-Anforderungen abgeschlossen sind. Ich habe versucht, Dispatch-Gruppen zu verwenden, aber ich kann es scheinbar nicht richtig machen.Warten Sie, bis mehrere AFNetworking-Anforderungen abgeschlossen sind.

Hier ist mein Code:

dispatch_group_t group = dispatch_group_create(); 

for (int k = 0; k < 10 ; k++) { 
    dispatch_group_enter(group); 

    [[AFHTTPSessionManager manager] GET:@"http://google.com/" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { 
     NSLog(@"success"); 
     dispatch_group_leave(group); 
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 
     NSLog(@"failure"); 
     dispatch_group_leave(group); 
    }]; 
} 

dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 

NSLog(@"DONE"); 

Das Problem ist, dass es auf dispatch_group_wait stecken bleibt, weil weder der Erfolg Block, noch die Fehlerblöcke genannt werden.

Wie kann ich es lösen?

+0

Haben Sie versucht, mit dispatch_group_notify? – jtbandes

+0

ja, das funktioniert. Aber das löst mein Problem nicht. Aufgrund der Art und Weise, wie die App erstellt wurde (ich habe das Projekt geerbt), muss ich die Ausführung der Methode stoppen. – guidev

+0

Das ist bedauerlich; Vielleicht sollten Sie in Betracht ziehen, es zu refaktorisieren. Wenn Sie den Thread blockieren, verschwenden Sie einen Thread, dessen einzige Aufgabe darin besteht, darauf zu warten, dass ein anderer Thread etwas tut. libdispatch legt ein Limit von 64 Threads fest, das zum Warten von Warteschlangen gestartet wird. Je nachdem, was Ihre App tut, kann dies zu einem Problem werden. – jtbandes

Antwort

6

Die Absende-Warteschlange für completionBlock. Wenn NULL (Standard), wird die Hauptwarteschlange verwendet.

dispatch_group_t group = dispatch_group_create(); 

dispatch_queue_t queue = dispatch_queue_create("com.app", DISPATCH_QUEUE_CONCURRENT); 

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; 
manager.completionQueue = queue; 
for(int k = 0; k < 10; k++) { 
    dispatch_group_enter(group); 

    dispatch_async(queue, ^{ 
     NSLog(@"%d", k); 
     [manager GET:@"http://baidu.com/" parameters:nil progress:nil success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) { 
      NSLog(@"success"); 
      dispatch_group_leave(group); 
     } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) { 
      NSLog(@"failure"); 
      dispatch_group_leave(group); 
     }]; 
    }); 
} 

dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 

NSLog(@"DONE"); 
0

die Sie interessieren,

dispatch_group_t group = dispatch_group_create(); 

for (int k = 0; k < 10 ; k++) { 
    dispatch_group_enter(group); 

    [[AFHTTPSessionManager manager] GET:@"http://google.com/" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { 
     NSLog(@"success"); 
     dispatch_group_leave(group); 
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 
     NSLog(@"failure"); 
     dispatch_group_leave(group); 
    }]; 
} 

dispatch_group_notify(group, dispatch_get_main_queue(), ^{ 

    NSLog(@"All done"); 

}); 

dispatch_group_notify wird aufgerufen, wenn alle Aufgaben abgeschlossen wird.

0

Sie können PromiseKit verwenden. Sehr leistungsfähig.

Sequential

 [self.manager GET:@"http://www.error-url.ss/" parameters:nil].then(^(id responseObject, AFHTTPRequestOperation *operation){ 
     NSLog(@"first request completed for operation: %@", operation.request.description); 
     return [self.manager GET:@"http://www.apple.com" parameters:nil]; 
    }).then(^{ 
     NSLog(@"second request completed"); 
    }).catch(^(NSError *error){ 
     NSLog(@"error happened: %@", error.localizedDescription); 
     NSLog(@"original operation: %@", error.userInfo[AFHTTPRequestOperationErrorKey]); 
    }); 

OR (wie pro Ihre Anforderung)

 [PMKPromise when:@[ 
         [self.operationManager GET:@"ip" parameters:nil].then(^(){numberOfOperationsCompleted ++;}), 
         [self.operationManager GET:@"get" parameters:nil].then(^(){numberOfOperationsCompleted ++;}) 
         ]].then(^(){ 
     //do something when all operations are finished 
    }); 
0

Sie können diese Hilfsfunktion verwenden, um den Hauptthread zu blockieren.

static inline void hxRunInMainLoop(void(^block)(BOOL *done)) { 
__block BOOL done = NO; 
block(&done); 
while (!done) { 
    [[NSRunLoop mainRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow:.1]]; 
} 
} 

Sie müssen auch einen Zähler implementieren und bei Erfolg oder Misserfolg erhöhen.

- (void)test { 
    __block int count = 0; 

    hxRunInMainLoop(^(BOOL *done) { 

    for (int i = 0; i < 10; i++) { 

    [AFHTTPSessionManager manager] GET:@"http://google.com/" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { 
     NSLog(@"success"); 
     count++; 
     if (count == 9) { 
     *done = YES; 
     } 
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 
     NSLog(@"failure"); 
     count++; 
     if (count == 9) { 
     *done = YES; 
     } 
    }]; 
} 

Dies blockiert den Hauptthread, bis done auf YES gesetzt ist.

Verwandte Themen