Ограничить скорость передачи данных NSURLConnection? (Дросселирование полосы пропускания)

Есть ли способ ограничить пропускную способность, используемую NSURLConnection, или я вынужден использовать методы CFNetwork?


person Enrico Ghirardi    schedule 09.11.2012    source источник


Ответы (1)


Да, но это некрасиво (работает согласно это сообщение списка рассылки):

  • Запустите NSURLConnection в фоновом потоке (вам нужно будет настроить цикл выполнения).
  • Спите в -connection:didReceiveData:.
  • Пересылайте данные в основной поток потокобезопасным способом.

Третий пункт немного сложнее сделать правильно, если делегатом является UIViewController, но что-то вроде этого должно работать, если delegate равно __weak или __unsafe_unretained:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
  [NSThread sleepForTimeInterval:...];
  [self performSelectorOnMainThread:@selector(notifyDelegateDidReceiveData:) withObject:data waitUntilDone:NO];
}

-(void)notifyDelegateDidReceiveData:(NSData*)data
{
  assert([NSThread isMainThread]);
  [delegate myConnectionWrapper:self didReceiveData:data];
}

Вычисление продолжительности сна нетривиально, потому что вы можете захотеть учесть накладные расходы TCP/IP, но [data length]+100 может быть правильным.

Если у вас несколько подключений и вы хотите регулировать общую пропускную способность, поместите их все в один и тот же фоновый поток/цикл выполнения (см. -performSelector:onThread:withObject:waitUntilDone:).

Я полагаю, что для версии CFNetwork вы прочитали этот пост о какао с любовью.

person tc.    schedule 09.11.2012
comment
Вау, спасибо за потрясающий ответ! Как вы сказали, это некрасиво, но я попробую и посмотрю, надежно ли это работает, если нет, я останусь с CFNetwork. Еще раз спасибо! - person Enrico Ghirardi; 10.11.2012
comment
@tc Метод NSURLConnection на самом деле не ограничивает скорость загрузки, а замедляет сохранение данных в локальном буфере! мы не можем ограничить данные, передаваемые методу -connection:didReceiveData:. Можем ли мы каким-то образом ограничить данные, считываемые из сокета, которые передаются в -connection:didReceiveData:? - person bikram990; 20.09.2013
comment
@ bikram990 Я надеялся, что это сделает read() и -connection:didReceiveData: в одном потоке. Если нет, то я бы посмотрел, поддерживают ли ASIHttpRequest или AFNetworking ограничение скорости; также может быть нетрудно добавить поддержку для него. - person tc.; 20.10.2013
comment
@tc ASIHttpRequest может ограничивать скорость, поскольку использует CFNetwork напрямую, но AFNetworking не может, поскольку использует NSURLConnection. Я просмотрел источник AFNetworking, кажется, что он может ограничивать скорость загрузки, но я не смог найти общедоступный интерфейс для этого в их примерах. - person bikram990; 21.10.2013
comment
@tc Я новичок в задаче c. Может быть, я что-то пропустил, но, насколько мне известно, NSURLConnection не может ограничить скорость загрузки. - person bikram990; 21.10.2013