En plus du sémaphore technique couverts de manière exhaustive dans d'autres réponses, nous pouvons maintenant utiliser XCTest dans Xcode 6 pour effectuer des tests asynchrones via XCTestExpectation
. Ceci élimine le besoin pour les sémaphores lors des tests de code asynchrone. Par exemple:
- (void)testDataTask
{
XCTestExpectation *expectation = [self expectationWithDescription:@"asynchronous request"];
NSURL *url = [NSURL URLWithString:@"http://www.apple.com"];
NSURLSessionTask *task = [self.session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
XCTAssertNil(error, @"dataTaskWithURL error %@", error);
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSInteger statusCode = [(NSHTTPURLResponse *) response statusCode];
XCTAssertEqual(statusCode, 200, @"status code was not 200; was %d", statusCode);
}
XCTAssert(data, @"data nil");
// do additional tests on the contents of the `data` object here, if you want
// when all done, Fulfill the expectation
[expectation fulfill];
}];
[task resume];
[self waitForExpectationsWithTimeout:10.0 handler:nil];
}
Pour le plaisir des futurs lecteurs, tandis que l'envoi de sémaphore technique est une merveilleuse technique lorsque cela est absolument nécessaire, je dois avouer que je vois beaucoup trop de nouveaux développeurs, peu familier avec bon asynchrone des modèles de programmation, gravitent autour trop vite sur les sémaphores comme un mécanisme général pour asynchrone à des routines de se comporter de manière synchrone. Le pire que j'ai vu beaucoup d'entre eux utilisent ce sémaphore de la technique à partir de la file d'attente principale (et il ne faut jamais bloquer la file d'attente principale dans la production d'applications).
Je sais que ce n'est pas le cas ici (lorsque cette question a été posté, il n'y avait pas un bon outil, comme XCTestExpectation
; aussi, dans ces suites de tests, nous devons nous assurer que le test n'est pas fini jusqu'à ce que l'appel asynchrone est fait). C'est un de ces rares situations où le sémaphore technique pour bloquer le thread principal peut être nécessaire.
Donc, avec mes excuses à l'auteur de cette question d'origine, pour qui le sémaphore est la technique du son, j'écris cet avertissement à tous ces nouveaux développeurs qui voient ce sémaphore technique et d'envisager de l'appliquer dans leur code comme une approche générale pour traiter avec des méthodes asynchrones: Être avertis que, neuf fois sur dix, le sémaphore technique n'est pas la meilleure approche quand encounting les opérations asynchrones. Au lieu de cela, vous familiariser avec l'achèvement de bloc/fermeture des motifs, ainsi que des délégué-protocole de motifs et de notifications. Ceux-ci sont souvent bien meilleures façons de composer avec les tâches asynchrones, plutôt que d'utiliser des sémaphores pour les faire se comporter de façon synchrone. Habituellement, il ya de bonnes raisons que les tâches asynchrones ont été conçus pour se comporter de manière asynchrone, afin d'utiliser le bon modèle asynchrone plutôt que d'essayer de les faire se comporter de façon synchrone.