Приложение сбоя синхронного запроса ASIHTTPRequest - PullRequest
0 голосов
/ 08 февраля 2012

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

Что я делаю для борьбы с этой проблемой, так это внедряю многопоточность в мое приложение с использованием спасательных сервисов «Grand Central Dispatch», которые, кажется, до сих пор очень легко осваивать.

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

Error Domain=ASIHTTPRequestErrorDomain Code=1 "A connection failure occurred" UserInfo=0x68052a0 {NSUnderlyingError=0x683d250 "The operation couldn’t be completed. Connection refused", NSLocalizedDescription=A connection failure occurred}

Вот мой код.

    - (IBAction)setRequestString:(NSString *)string
    {
        //Set database address
        NSMutableString *databaseURL = [[NSMutableString alloc] initWithString:@"http://192.168.1.1:8778/Data/"]; // iphone development

        //PHP file name is being set from the parent view
        [databaseURL appendString:string];

        //call ASIHTTP delegates (Used to connect to database)
        NSURL *url = [NSURL URLWithString:databaseURL];

        //Used to Check which ASI cache to use (also used in requestFinished
        xmlFileName = [[NSString alloc] initWithFormat:string];  

        //Set up multithread with GCD
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);


        //Create If statments here to set up the different caches to be passed down to the next view
        if ([string isEqualToString:@"high.xml"]){     
            //Cache stuff goes in here
            ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
            [request setDownloadCache:[ASIDownloadCache sharedCache]];
            [request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
            [request setCachePolicy:ASIOnlyLoadIfNotCachedCachePolicy];
            [request setSecondsToCache:60*60*24*30]; // Cache for 30 days - this will change to cache until DBVersion changes
            [request setDelegate:self]; // this calls the delegate function requestFinished
            dispatch_sync(queue, ^ {
                [request startSynchronous];
            });
        }else if ([string isEqualToString:@"low.xml"]){     
            //Cache stuff goes in here
            ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
            [request setDownloadCache:[ASIDownloadCache sharedCache]];
            [request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
            [request setCachePolicy:ASIOnlyLoadIfNotCachedCachePolicy];
            [request setSecondsToCache:60*60*24*30]; // Cache for 30 days - this will change to cache until DBVersion changes
            [request setDelegate:self]; // this calls the delegate function requestFinished
            dispatch_sync(queue, ^ {
                [request startSynchronous];
            });
        }
   }

    - (void)requestFinished:(ASIHTTPRequest *)request
    {  
//.... etc

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

- (IBAction)grabURL:(id)sender
{
  NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
  ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
  [request startSynchronous];
  NSError *error = [request error];
  if (!error) {
    NSString *response = [request responseString];
  }
}

однако я работаю с данными .. так что эта строка

NSString *response = [request responseString];

не будет работать? доза должна быть NSData .. и т. д. Я не знаю, если кто-то может мне помочь, это было бы здорово.

Ответы [ 2 ]

0 голосов
/ 08 февраля 2012

Рассматривали ли вы просто добавление последовательной очереди в свой код?

dispatch_queue_t queue = dispatch_queue_create("com.myapp", NULL);

Вы используете параллельный поток, и он вызывает несколько операций одновременно. Кроме того, правильно оберните код ASIHttpRequest в блоки очереди.

Попробуйте и дайте нам знать

0 голосов
/ 08 февраля 2012

Вы можете использовать nsoperationqueue ... вы можете создать один NSoperationInvoke и добавить их в NSoperationQueue по порядку (после получения данных, отправляя другой запрос) ... Вы можете добавить наблюдателя в NSOperationQueue, чтобы гарантировать, что сколько запросов будет обрабатываться одновременно... в вашем случае это будет всего один ... после получения уведомления в наблюдателе, что синхронный процесс завершен, он вызовет селектор по PerformonMainThread для запуска другого запроса в самом наблюдателе ...

при NSString *response = [request responseString];

проблеме вы можете проверить объект запроса с помощью [request iskindofClass:[ClassName class]]; или nslog ("% @", [request description]);

это скажет, какой тип запроса объектаесть

...