Новое значение доступно только в sendAsynchronousRequest — Swift

var arrayData: [String] = []

let bodyData = "parameter=test"

let URL: NSURL = NSURL(string: "Link to php file")
let request:NSMutableURLRequest = NSMutableURLRequest(URL:URL)
request.HTTPMethod = "POST"
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue())
{
    (response, data, error) in
        var output = NSString(data: data, encoding: NSUTF8StringEncoding)

        self.arrayData = self.JSONParseArray(output)

        println(self.arrayData) //Print the result
}

println(self.arrayData) //Print nothing

Похоже, что новое значение доступно только в sendAsynchronousRequest.

Есть ли способ сделать новое значение доступным из sendAsynchronousRequest?


person Clément Bisaillon    schedule 27.08.2014    source источник
comment
возможный дубликат Получение данных из блока завершения NSURLResponse - (Разве вы не задавали (и удаляли) очень похожий вопрос вчера? -swift" title="переменная в замыкании доступна только в замыкании swift">stackoverflow.com/questions/25513767/)   -  person Martin R    schedule 27.08.2014


Ответы (2)


sendAsynchronousRequest, как следует из названия, является асинхронным. Таким образом, ваш последний println выполняется до того, как запрос будет завершен. После запуска обработчика завершения новые данные будут доступны для всех читателей (в этом обработчике или за его пределами).

person Rob Napier    schedule 27.08.2014
comment
Хорошо, и как я могу это исправить? - person Clément Bisaillon; 27.08.2014
comment
Что ты хочешь делать? В приведенном выше коде вы уже исправили это. Вы println() внутри обработчика завершения, который запускается в нужное время. Чего еще вы пытаетесь достичь? - person Rob Napier; 27.08.2014
comment
Я не хочу, чтобы последний println имел значение, потому что мне нужно это значение для моей функции tableView - person Clément Bisaillon; 27.08.2014
comment
Это будет синхронный запрос (который доступен на NSURLConnection, но тогда вы заблокируете весь свой пользовательский интерфейс, пока ждете подключения. Вы не можете заставить табличное представление ждать сетевого подключения. В обработчике завершения скажите своей ячейке tableview обновить себя. - person Rob Napier; 27.08.2014

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

Вот что происходит:

  1. ты звонишь sendAsynchronousRequest
  2. запрос запущен, но функция немедленно возвращается (не ждет завершения запроса)
  3. строка println выполняется следующей (последняя строка в вашем коде)
  4. некоторое время спустя асинхронный запрос завершается, и выполняется закрытие
  5. замыкание присваивает значение self.arrayData

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

person Antonio    schedule 27.08.2014
comment
Хорошо, и как я могу это исправить? - person Clément Bisaillon; 27.08.2014
comment
Вы не можете сделать это линейным способом. Как уже упоминалось в моем ответе, вам нужно что-то делать внутри замыкания - обычно вызывают метод экземпляра класса для обработки полученного значения. - person Antonio; 27.08.2014