Ошибка или путаница в документации Apple SDK по NSURLConnection? - PullRequest
2 голосов
/ 07 мая 2009

Я недавно изучал Apple SDK (для iPhone и т. Д.) И наткнулся на то, чего я не могу понять. В документах для "Использование NSURLConnection" от http://developer.apple.com/documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html

Я нашел странный фрагмент объяснения и пример кода. Сначала говорится:

Загрузка начинается сразу после получения сообщения initWithRequest: Delegate:. Его можно отменить в любое время до того, как делегат получит сообщение connectionDidFinishLoading: или connection: didFailWithError: отправив соединению сообщение об отмене.

Далее показывается следующий фрагмент кода:

  NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

  if (theConnection) {

    // Create the NSMutableData that will hold

    // the received data

    // receivedData is declared as a method instance elsewhere

    receivedData=[[NSMutableData data] retain];

  } else {

    // inform the user that the download could not be made

  }

Итак, мне кажется, что загрузка должна начаться сразу в другом потоке, как только инициализируется соединение. Это ясно, потому что код не блокирует и отправляет сообщения делегату, в данном случае, самостоятельно. Тем не менее, выделение (в стиле авто-релиза) ReceiveData происходит после запускается другой поток. Разве это не опасное состояние гонки? Может ли это привести к сбою, утечке памяти или потере данных в случае очень быстрого отклика сервера (например, через устройство с обратной связью) или в случае неудачного планирования потоков? Разве не имеет смысла выделять полученныйData до инициализации theConnection, а затем просто освободить его в другом случае выше?

Я так запутался в этом куске кода, надеюсь, кто-нибудь сможет пролить свет на это для меня. Спасибо за любую информацию,

Руди Чилибрази

Ответы [ 2 ]

6 голосов
/ 07 мая 2009

Нет условий гонки. Загрузка начинается в фоновом режиме в отдельном потоке, но сообщения, отправляемые делегату для информирования вас о ходе загрузки, всегда вызываются в потоке, который начал загрузку.

Вы, безусловно, можете выделить NSData до создания соединения, если это более понятно для вас. Вы даже можете выделить его в методе connection: didReceiveData: если вы хотите убедиться, что NSData не был выделен, если не было данных для хранения.

Я думаю, что пример написан так, чтобы он был как можно более коротким, чтобы не путать презентацию с большим количеством ненужного кода.

С документация для NSURLConnection :

Методы делегатов NSURLConnection позволить объекту получить информационные обратные вызовы о асинхронная загрузка URL-запроса. Другие методы делегата обеспечивают средства, которые позволяют делегату настроить процесс выполнения асинхронная загрузка URL.

Обратите внимание, что эти методы делегата будут быть вызванным в теме, которая началась операция асинхронной загрузки для связанный объект NSURLConnection.

2 голосов
/ 07 мая 2009

Здесь нет условий гонки. NSURLConnection использует NSRunLoop для отправки своих событий. Поэтому никакие данные не могут быть получены до тех пор, пока не начнется следующий цикл обработки событий.

Это означает, что вызовы connection:didReceiveData: не будут выполняться до следующего цикла событий, независимо от того, когда данные действительно вернутся, и что connection:didReceiveData: будет вызываться в потоке, который начал загрузку. Таким образом, у вас есть оставшаяся часть цикла выполнения, чтобы привести все в порядок. «Немедленно» означает здесь «вам не нужно ничего делать, чтобы начать это».

Это не гипотеза или изменяемая деталь реализации; это основано на принципах дизайна Какао. Чтобы лучше понять Какао, предположим, что почти все происходит в главном потоке. Хотя фреймворки могут порождать потоки как детали реализации, они всегда создают иллюзию, что они этого не делают. Поэтому асинхронные операции по своей природе всегда будут отображаться в более позднем цикле событий. Кооперативная, а не преждевременная многозадачность - это способ Какао.

...