1

Я пытаюсь запустить второе NSURLConnection после запуска первого. Моя первая работает отлично: все делегаты все называются, и все выполняется, как и планировалось. Однако после того, как первый закончится, я создаю второй, и ничего не происходит (делегат никогда не вызывается). Что может случиться? Я знаю, что не могу повторно использовать одно и то же NSURLConnection, но я повторно инициализую его, прежде чем снова использовать его, поэтому это должно быть совершенно новое соединение.Использование NSURLConnection Несколько раз

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

if (connection) { 
    [connection cancel]; 
} 

currentResponse = nil; 
error = nil; 

connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO]; 
if (!connection) { 
    NSLog(@"Connection could not be initialized."); 
    [self connectionFinished]; 
} else { 
    [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
    [connection start]; 
} 
+0

Это соединение вообще создано? Получаете ли вы, что «Соединение не может быть инициализировано». сообщение регистрируется? Является ли метод, в котором находится этот код? – rdelmar

+0

Этот код вызывается, и соединение инициализируется оба раза. Сообщение об ошибке инициализации никогда не регистрируется. – ferson2020

+0

Вы всегда в главной теме? –

ответ

2

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

Несколько возможных решений:

  1. Вы можете выполнять сетевые операции синхронно на этом фоне работе вашего (это единственный раз, когда вы должны делать синхронные операции сети). Это самое простое решение, хотя вы не объяснили, что вы делаете с вашим NSURLConnection, поэтому этот метод может или не может работать для вас. Но если вы просто пытаетесь загрузить что-нибудь из URL, вы можете сделать:

    NSData *data = [NSData dataWithContentsOfURL:url 
                options:0 
                 error:&error]; 
    

    Этот подход не работает, если вы делаете какой-либо немного более сложным, что требует NSURLConnectionDataDelegate методы, такие challenge- аутентификация ответа или если вы используете потоки с использованием didReceiveData, чтобы уменьшить объем памяти вашего приложения или по соображениям производительности и т. д. Но если вы просто пытаетесь загрузить данные с удаленного сервера (например, извлечение изображения, фида XML/JSON и т. д.), это проще всего.

  2. В том же духе (то есть вам не нужны NSURLConnectionDataDelegate методы), но вы, вы создаете какой-то богатый NSURLRequest для подключения, то вы можете использовать либо sendAsynchronousRequest или sendSynchronousRequest.

  3. Если вам нужны NSURLConnectionDataDelegate вызовы, вы можете использовать setDelegateQueue (обозначения NSOperationQueue) или scheduleInRunLoop (обозначающие NSRunLoop), и он будет автоматически отправлять обновления подключения к соответствующей очереди/runloop. Просто убедитесь, что initWithRequest с использованием опции startImmediatelyNO, установите делегатскую очередь или runloop, а затем start соединение. С помощью этой техники вы сохраняете полное богатство NSURLConnectionDataDelegate, если вам это абсолютно необходимо.

  4. В качестве альтернативы, если вы не используете операционные очереди, вы также можете сохранить свою фоновую операцию до тех пор, пока соединение не будет выполнено. Такой подход дает вам синхронное поведение в фоновом режиме (поддерживая ваше соединение), сохраняя при этом методы NSURLConnectionDataDelegate. Этот метод продемонстрирован Apple's XMLPerformance Sample (см. Метод CocoaXMLParser.m и LibXMLParser.м), где они инициируют NSURLConnection, а затем с помощью следующей конструкции, чтобы сохранить операцию фона в живых до тех пор, NSURLConnectionDataDelegate методы не в конечном итоге установки переменной done экземпляра:

    do { 
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
              beforeDate:[NSDate distantFuture]]; 
    } while (!done); 
    

Признаюсь, я найти этот окончательный подход смутно неудовлетворяя и будет склоняться к другим альтернативам, в зависимости от того, какую гибкость и функциональность вам нужно от вашего NSURLConnection. Чтобы мы предоставили более содержательный совет, вам просто нужно предоставить дополнительную информацию о (a) той работе, которую вы выполняете в своих методах NSURLConnectionDataDelegate; и (б) какую технологию вы используете для запуска кода в фоновом режиме.

Еще несколько вариантов, также можете видеть GCD and async NSURLConnection.

+0

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

Смежные вопросы