Objective-C: запросы сервера в потоке (например, AsyncTask в Android)

Я хотел бы запустить запрос сервера, вы можете отменить.

Моя идея - запустить запрос в потоке, чтобы пользовательский интерфейс не зависал. Таким образом, вы можете убить весь поток, включая запрос, нажав кнопку "Отмена".

С Android он работает: запрос сервера запускается в "AsyncTask" и в методе onReturn(), который я могу отреагировать, как только закончится запрос сервера.

Как я могу реализовать это с помощью Objective-C в iOS? Моя первая попытка была "NSInvocationOperation". Вы можете отменить операцию, но ее трудно обрабатывать, когда запрос завершен, и результаты доступны. Я думаю, что NSInvocationOperation не является решением для моей проблемы.

Ты бы мне порекомендовал? Является ли NSThread правильным выбором для меня?

Большое спасибо!

Ответ 1

Внимание!

Th - очень старый ответ, теперь здесь только для исторических целей.

Прекрасная библиотека ASIHttpRequest больше не существует; теперь технология совершенно другая.


Это невероятно просто сделать с помощью ASIHttpRequest.

(Asynchronous настолько прост, нет причин, по которым вы это сделаете не асинхронно).

Вот некоторые грубые выдержки, которые могут вас завести.

...
ASIFormDataRequest *request;
...
NSURL *url = [NSURL URLWithString:@"https://blah.blah/blah.cgi?blah"];
request = [ASIFormDataRequest requestWithURL:url];

[request setPostValue:@"fred" forKey:@"username"];
[request setPostValue:@"flint" forKey:@"passie"];
[request setPostValue:@"stone" forKey:@"town"];

// send up data...
[request setData:[NSData dataWithBytes:blah length:blah] forKey:@"thefile"];

// or perhaps something like...
[request setData:imageData withFileName:@"blah.png"
        andContentType:@"image/jpeg" forKey:@"photoimage"];

[request setDelegate:self];
[request setDidFinishSelector:@selector(postingDone:)];
[request setDidFailSelector:@selector(postingDoneProblem:)];
[request startAsynchronous];
...

-(void) postingDone:(ASIHTTPRequest *)request
    {
    // it worked
    }
-(void) postingDoneProblem:(ASIHTTPRequest *)request
    {
    // failed
    }

Не может быть проще. Вы в основном просто печатаете поля и значения.

По вашему вопросу, вот как вы отменяете запрос "в полете" ... просто установите делегат на нуль и затем отмените его.

  [myRequest setDelegate:nil];
  [myRequest cancel];
  [myRequest release];

ASIHttpRequest - это "чудо-библиотека". Если вы новичок в iOS, ASIHttpRequest - это просто самая популярная сторонняя библиотека. По сути, каждое приложение iPhone из 300 000 iPhone-приложений использует его.

Если возможно, БУДЬТЕ УВЕРЕНЫ, чтобы пожертвовать несколько баксов парню - если он перестанет поддерживать эту библиотеку, запущено 100 000 программистов iPhone!

документация тривиальна, ребенок может следовать за ней:
http://allseeing-i.com/ASIHTTPRequest/How-to-use
"Создание асинхронного запроса"

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

Ответ 2

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

Также передача данных происходит в фоновом режиме, так что пользовательский интерфейс остается отзывчивым.

Ответ 3

Cocoa встроенный асинхронный сетевой код не основан на потоках, но работает с событиями цикла цикла, но результат (асинхронные соединения) тот же.

Создайте NSURLConnection с помощью +[NSURLConnection connectionWithRequest:delegate:]. Делегат, которого вы установили, будет проинформирован о ходе соединения и может в любое время отменить его с помощью -[NSURLConnection cancel].

Ответ 4

Отметьте ASIHTTPRequest, в частности, подкласс ASINetworkQueue, который описывается как:

ASINetworkQueue

Подкласс NSOperationQueue, который могут использоваться для отслеживания прогресса в несколько запросов.

Я использовал ASIHTTPRequest только для одного синхронного запроса для загрузки непосредственно на диск, что было легко реализовать, но я слышал хорошие отчеты об использовании очередей для одновременного управления несколькими асинхронными запросами сервера.

Ответ 5

В рекомендациях по использованию +[NSURLConnection connectionWithRequest:delegate:] следует отметить, что его следует вызывать только из основного потока с iOS 4.

см. http://blog.mugunthkumar.com/coding/ios4-issue-nsurlconnection-and-nsoperation/ для примера того, как с этим справиться.