将 URL 数据保存到变量

Saving URL data to a variable

所以我试图从 RESTful API 中获取一个简单的数据字符串。响应如下所示:

Hello

它没有格式化为 XML 或 JSON 或任何只是一个简单的字符串,因为一次只传回一个单词。所以这就是我的 swift 的样子:

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()

在进入 dispatch_async() 方法之前,我在“str”变量中得到了正确的数据。但是当我进入 dispatch_async() 方法时,“str”变量变为 nil,我不确定为什么。我只是想将单个单词保存在我的 class 中的一个变量中,所以如果我要解决这个完全错误的问题,请告诉我。我真的很感激我能得到的任何帮助。谢谢!

编辑

好的,所以我应该在我第一次发帖时就包含这个。我也试过这个:

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()

但是当我这样做时,字符串不会在 completionHandler 完成后保留在 self.spellCorrection 变量中。所以我的问题是,在 completionHandler 完成后,我应该怎么做才能将字符串保留在 self.spellCorrection 变量中?谢谢!

更多详情

在 viewDidLoad 中:

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)
}

我认为您首先不需要调用 dispatch_async。您没有做任何需要在主线程上完成的工作。

正如您在答案的 "More Details" 部分下添加的代码所明确的那样,即

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 在 async 块中正确打印的原因——因为在那个时候,代码肯定已经执行;但是你不能像你所做的那样直接在异步块之外打印更新的值,因为异步代码还没有完成执行。

所以,是的,您的 self.spellCorrection 实际上已正确设置,但您必须等到异步代码执行后才能检查新值。检查更新值的可靠方法实际上是在异步块中打印它。