Сохранение данных URL в переменную

Итак, я пытаюсь получить простую строку данных из RESTful API. Вот как выглядит ответ:

Hello

Он не отформатирован в XML или JSON или чем-то еще, а представляет собой простую строку, потому что за раз передается только одно слово. Итак, вот как выглядит мой свифт:

let task = session.dataTaskWithURL(url!, completionHandler: { (data, response, error) -> Void in

    if error != nil {
        println("error: \(error.localizedDescription): \(error.userInfo)")
    }
    
    var withNewLine:NSString = NSString(data: data, encoding: NSUTF8StringEncoding)!
    let str:NSString = withNewLine.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())

    dispatch_async(dispatch_get_main_queue(), {
        self.spellCorrection = str
    })
})

task.resume()

Я получаю правильные данные обратно в переменную str, прежде чем перейти к методу dispatch_async(). Но когда я захожу в метод dispatch_async(), переменная str становится равной нулю, и я не знаю, почему. Я просто пытаюсь сохранить одно слово в переменной в своем классе, поэтому, если я делаю это совершенно неправильно, дайте мне знать. Я был бы очень признателен за любую помощь, которую я могу получить. Спасибо!

Редактировать

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

let task = session.dataTaskWithURL(url!, completionHandler: { (data, response, error) -> Void in

    if error != nil {
        println("error: \(error.localizedDescription): \(error.userInfo)")
    }
    
    var withNewLine:NSString = NSString(data: data, encoding: NSUTF8StringEncoding)!
    self.spellCorrection = withNewLine.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
})

task.resume()

Но когда я делаю это, строка не остается в переменной self.spellCorrection после завершения завершенияHandler. Итак, мой вопрос: что мне делать, чтобы сохранить строку в переменной self.spellCorrection после завершения завершения? Спасибо!

Подробнее

В представленииDidLoad:

var spellCorrection: NSString = ""
//First print
println(self.spellCorrection)

В методе, который я вызываю позже, у меня есть:

func spellCheck() {
    var check: String = "http://theURL.com/?text=" + condenseWhitespace(self.lastTypedWord)
    let url = NSURL(string: check)
    let task = session.dataTaskWithURL(url!, completionHandler: { (data, response, error) -> Void in
        
        if error != nil {
            println("error: \(error.localizedDescription): \(error.userInfo)")
        }
        
        var withNewLine:NSString = NSString(data: data, encoding: NSUTF8StringEncoding)!
        self.spellCorrection = withNewLine.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
    }).resume()
    //Print after the completionHandler
    println(self.spellCorrection)
}

person Danwakeem    schedule 29.01.2015    source источник
comment
@LyndseyScott Если вы посмотрите на раздел «Правка» выше, я избавился от dispatch_async. Я просто пытаюсь получить доступ к self.spellCorrection внутри завершенияHandler.   -  person Danwakeem    schedule 29.01.2015
comment
Как я сказал в другом комментарии, в своем коде вы не пытаетесь получить доступ к self.spellCorrection... вы пытаетесь установить self.spellCorrection. Я спрашиваю, где вы пытаетесь получить доступ к нему? Потому что я предполагаю, что вы пытаетесь получить к нему доступ до того, как он был установлен.   -  person Lyndsey Scott    schedule 29.01.2015
comment
@LyndseyScott Извините, я путаю терминологию. Я хотел сказать, что не могу установить self.spellCorrection в завершенииHandler. Когда завершениеHandler завершилось, self.spellCorrection возвращается к тому, к чему он был первоначально инициализирован.   -  person Danwakeem    schedule 29.01.2015
comment
И я спрашиваю, где вы проверяете его значение, чтобы узнать, что оно возвращается к тому, к чему оно было первоначально инициализировано, потому что это очень важно. Это может вообще не возвращаться ... Очень возможно, что вы просто проверяете не то место в своем коде.   -  person Lyndsey Scott    schedule 29.01.2015
comment
@LyndseyScott Хорошо, я сначала инициализирую self.spellCorrection в методе viewDidLoad. Затем я вызываю другой метод, в котором есть мой завершениеHandler, и если я печатаю self.spellCorrection в завершенииHandler, я получаю правильную строку, но когда я печатаю self.spellCorrection вне завершенияHandler, я не получаю правильных результатов. Если это трудно понять, я добавил больше кода в исходный вопрос.   -  person Danwakeem    schedule 29.01.2015
comment
Я думаю, что знаю, что происходит, но все же, пожалуйста, добавьте код, если вы пытаетесь напечатать строку за пределами блока, чтобы я мог убедиться, что вы делаете это тем же методом.   -  person Lyndsey Scott    schedule 29.01.2015


Ответы (2)


Как видно из кода, который вы добавили в разделе «Подробнее» вашего ответа, т.е.

let task: Void = session.dataTaskWithURL(url!, completionHandler: { (data, response, error) -> Void in

   // ...

   self.spellCorrection =    withNewLine.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNew lineCharacterSet())
   println(spellCorrection)
}).resume()

println(self.spellCorrection)

печатая self.spellCorrection непосредственно вне блока, вы пытаетесь напечатать его до того, как он будет установлен в асинхронном блоке dataTaskWithURL.

Асинхронный блок выполняется в фоновом режиме, поэтому код, написанный сразу после выполнения вашего блока в основном потоке, код в асинхронном блоке еще не будет завершен. Вот почему self.spellCorrection правильно печатается внутри асинхронного блока — потому что в этот момент код определенно выполняется; но вы не можете распечатать обновленное значение непосредственно за пределами асинхронного блока, как вы это сделали, потому что асинхронный код еще не завершил выполнение.

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

person Lyndsey Scott    schedule 29.01.2015
comment
Хорошо, это имеет смысл. Я не понял, что это был асинхронный запрос. Вероятно, следовало более внимательно прочитать Справочник по классам. Большое спасибо за вашу помощь @LyndseyScott - person Danwakeem; 29.01.2015

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

person Dani A    schedule 29.01.2015
comment
Когда я нахожусь в завершении завершенияHandler, я не могу получить доступ к self.spellCorrection. Поэтому я использовал dispatch_async, чтобы получить доступ к self.spellCorrection, но проблема в том, что когда я это делаю, я, похоже, не могу получить доступ к переменной str. Есть ли какой-то другой метод, который я должен использовать для сохранения переменных из завершенияHandler? - person Danwakeem; 29.01.2015
comment
@LyndseyScott Я удалил это. Я заменил dispatch_async на self.spellCorrection = str. Но проблема в том, что я не могу получить доступ к переменной self.spellCorrection из завершенияHandler. Итак, мой вопрос: что мне делать, чтобы сохранить данные, которые я получаю, и сохранить переменную str в переменной self.spellCorrection? - person Danwakeem; 29.01.2015
comment
@ user2298020 Где в вашем коде вы пытаетесь получить к нему доступ? - person Lyndsey Scott; 29.01.2015
comment
@LyndseyScott Я пытаюсь получить доступ к self.spellCorrection внутри завершенияHandler. Если вы посмотрите на приведенный выше код, вы сможете увидеть, где я получаю доступ к self.spellCorrection. self.spellCorrection — это просто член класса. - person Danwakeem; 29.01.2015
comment
@user2298020 user2298020 В своем коде вы не пытаетесь получить доступ к self.spellCorrection... вы пытаетесь установить self.spellCorrection. Я спрашиваю, где вы пытаетесь получить доступ к нему? Потому что я предполагаю, что вы пытаетесь получить к нему доступ до того, как он был установлен. - person Lyndsey Scott; 29.01.2015
comment
@LyndseyScott, черт возьми, извини, я использую неправильную терминологию. Я хотел сказать, что не могу установить self.spellCorrection внутри завершенияHandler. - person Danwakeem; 29.01.2015