В дополнение к семафорной технике, подробно рассмотренной в других ответах, теперь мы можем использовать XCTest в Xcode 6 для выполнения асинхронных тестов с помощью XCTestExpectation
.Это устраняет необходимость в семафорах при тестировании асинхронного кода.Например:
- (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];
}
Ради будущих читателей, хотя техника рассылки семафоров является замечательной техникой, когда она абсолютно необходима, я должен признаться, что вижу слишком много новых разработчиков, незнакомых с хорошими асинхроннымиШаблоны программирования, слишком тяготеющие к семафорам, как общий механизм для синхронного поведения асинхронных подпрограмм.Хуже того, я видел, что многие из них используют эту технику семафоров из основной очереди (и мы никогда не должны блокировать основную очередь в производственных приложениях).
Я знаю, что это не тот случай (когда этот вопрос былопубликовано, что не было такого хорошего инструмента, как XCTestExpectation
, также в этих тестах мы должны убедиться, что тест не завершится, пока не будет выполнен асинхронный вызов).Это одна из тех редких ситуаций, когда может понадобиться техника семафора для блокировки основного потока.
Итак, приношу свои извинения автору этого оригинального вопроса, для которого техника семафора является надежной, я пишу это предупреждение всем тем новым разработчикам, которые видят эту технику семафора и рассматривают возможность применения ее в своем коде какОбщий подход к работе с асинхронными методами: Предупреждаем, что в девяти случаях из десяти метод семафора является , а не лучшим подходом при включении асинхронных операций.Вместо этого ознакомьтесь с шаблонами завершения / закрытия, а также с шаблонами протоколов делегирования и уведомлениями.Часто это гораздо лучшие способы решения асинхронных задач, чем использование семафоров для синхронного поведения.Обычно есть веские причины, по которым асинхронные задачи были разработаны для асинхронного поведения, поэтому используйте правильный асинхронный шаблон, а не пытайтесь заставить их вести себя синхронно.