(Асинхронный) NSURLConnection: что происходит под ним? - PullRequest
3 голосов
/ 25 марта 2011

Я понимаю, что он должен заботиться о безобразии запуска потока, чтобы сделать сетевой запрос, а затем, вероятно, вызвать performSelectorOnMainThread: с моим методом делегата.1005 * это когда занимаешься программированием под iOS, и работает отлично.Тем не менее, я хотел бы знать, как я мог бы заставить его работать, в контексте (например) утилиты командной строки, где нет UIApplication с обработкой событий и т.д.и кажется, что программа завершается, как только возвращается асинхронный вызов, прежде чем могут быть вызваны методы делегата.Я очень хочу получить более глубокое понимание того, как это работает.

Ответы [ 2 ]

7 голосов
/ 26 марта 2011

Согласно документам , методы делегата соединения вызываются в том же потоке, из которого было запущено соединение.Таким образом, чтобы этот поток работал до тех пор, пока соединение не успеет выполнить свою работу:

int main(int argc, char *argv[])
{   
    // ...
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:del startImmediately:YES];
    CFRunLoopRun();    // Run this run loop, run!
    // ...
}

Затем делегат может остановить цикл выполнения, когда соединение сообщает, что оно завершено:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    // This returns control to wherever you called
    // CFRunLoopRun() from, so you can still clean up
    // or do other interesting things.
    CFRunLoopStop(CFRunLoopGetCurrent());
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    NSLog(@"Error: %@", error);
    CFRunLoopStop(CFRunLoopGetCurrent());
}
2 голосов
/ 25 марта 2011

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

И по умолчанию цикл выполнения должен работать в режиме по умолчанию, чтобы эти методы делегата запускались. Вот почему, например, по умолчанию, если вы запускаете асинхронное соединение из основного потока, ваши методы делегата не будут срабатывать, пока пользователь прокручивает представление таблицы или что-то в этом роде.

Но вы можете изменить это, запланировав обратные вызовы делегатов на любой другой цикл выполнения, который вы хотите, и / или любой режим цикла выполнения, который вы хотите использовать - [NSURLConnection scheduleInRunLoop: forMode:]

Надеюсь, ты об этом спрашивал?

...