Вы заметили, что dispatch_after работает на 10% медленнее на устройствах iOS?
В последнее время яя использовал dispatch_after вместо executeSelector: withObject: afterDelay, когда я хочу вызвать некоторый код после задержки. Код чище, у него есть доступ к закрытой области видимости, я могу поместить код в строку вместо написания одноразового метода и т. Д. И т. Д.
Мой код может выглядеть так:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
delay * NSEC_PER_SEC),
dispatch_get_main_queue(),
^{
//Delayed-execution code goes here.
}
);
Однако недавно я обнаружил, что время выполнения этого кода, по-видимому, работает примерно на 10% медленнее, чем запрошено. Если я запрашиваю задержку в 10 секунд, мой блок исполняется примерно через 11 секунд. Это на устройстве iOS. Кажется, что времена на симуляторе совпадают.
Код яЯ использую, чтобы проверить это довольно просто: я
NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
delay * NSEC_PER_SEC),
dispatch_get_main_queue(),
^{
NSTimeInterval actualDelay = [NSDate timeIntervalSinceReferenceDate] - startTime;
NSLog(@"Requested delay = %.3f. Atual delay = %.3f", delay, actualDelay);
//Delayed-execution code goes here.
}
);
Мы тестировали на устройствах от iOS 4S до iPad Air, и дополнительная задержка довольно стабильна. У меня нетЯ пока не тестировал его на более старых устройствах, таких как iPhone 4 или iPad 2, хотя скоро я это сделаю.
Я мог бы ожидать 20-50 мсотстойные» в задержке, но постоянное превышение на 10% - 11% является странным.
мы добавили "фактор выдумки " на мой код, который корректирует дополнительную задержку, но я нахожу это удивительным:
#define delay_fudge 0.912557 //Value calculated based on averages from testing.
NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
delay * delay_fudge * NSEC_PER_SEC),
dispatch_get_main_queue(),
^{
NSTimeInterval actualDelay = [NSDate timeIntervalSinceReferenceDate] - startTime;
NSLog(@"Requested delay = %.3f. Actual delay = %.3f", delay, actualDelay);
//Delayed-execution code goes here.
}
);
Я, вероятно, должен сделать больше анализа и посмотреть, есть ли фиксированное увеличение задержки плюс коэффициент задержки или прямая процентная задержка, или, возможно, некоторая нелинейная шкала ошибки, но сейчас простой множитель, кажется, работает довольно хорошо.