【问题标题】:Contents of Dictionary not accessible outside of NSURLConnection Function在 NSURLConnection 函数之外无法访问字典的内容
【发布时间】:2015-06-26 19:19:37
【问题描述】:

我有一个函数,它接收一个字符串并返回一个通过 URL 请求填充的字典。我的函数将字符串分配给 JSON 对象,使用 SwiftyJSON 检索。属性已更新,但在退出 NSURLConnection.sendAsynchronousRequest 函数后,它们将无法访问。

所以对于 1、2 和 3 printlns,数组打印正确,但在 4 上打印不正确。代码如下:

func parseJSON(id:String) -> Dictionary<String, JSON> {
    var properties = [String:JSON]()
    var postEndpoint = "http://localhost:3000/properties/\(id)"
    var urlRequest = NSURLRequest(URL: NSURL(string: postEndpoint)!)

    NSURLConnection.sendAsynchronousRequest(urlRequest, queue: NSOperationQueue(), completionHandler: {
        (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in

        if let anError = error {
            println("error calling GET on /properties/\(id)")
        }
        else {
            let post = JSON(data: data)
            if let title = post["name"].string {
                for (index: String, subJson:JSON) in post {
                    properties[index] = subJson
                }
                println("1: \(properties)")
            }
            else {
                println("error parsing response from POST on /posts")
            }
            println("2 \(properties)")
        }
        println("3 \(properties)")
    })
    println("4 \(properties)")
    return ds1Properties
}

同样重要的是要注意 4 在 1、2 和 3 之前打印出来,这让我认为 NSURLConnection 是稍后调用的,因此返回值在离开 parseJSON 之前不会更新功能。

【问题讨论】:

  • 您的网络请求正在异步完成。首先打印 4,因为 Web 请求需要时间。一旦请求完成,就会调用完成块。
  • 那么如何在没有等待网络请求完成的情况下阻止函数返回呢?
  • 您不应延迟其返回。这是非常非常非常糟糕的事情,更糟糕的是。你应该去阅读一些关于异步与同步的背景知识,然后再问更多问题。目前,您的知识太基础,无法为您提供解决方案。你需要先做好准备。
  • 有很多工具可供您正确处理异步请求。您可以从完成块中调用一个函数,该函数将使用 JSON 执行您需要完成的任何操作。您可以发布您的 json 已完成的通知并让侦听器处理它。然而,网络调用之类的事情是异步的,你不应该试图对抗它。
  • 抱歉,我说错了。我熟悉同步和异步请求的概念。当我说“防止返回”时,我的意思是我应该使用什么替代方法才能在函数返回之前访问数据。我将使用同步调用重做这个。感谢您的帮助!

标签: ios json swift rest


【解决方案1】:

您需要了解异步的含义以及如何进行异步编程。

使用异步代码,每一行不是一个接一个地执行,它们是并行执行的。

当您调用 parseJSON() 时,它将立即完成并返回,但在其中您调用了 sendAsynchronousRequest。这会启动另一个并行运行的线程(你知道线程是什么吗?)。此线程可能不会在几秒钟内完成。因此,步骤 1、2 和 3 可能要等到步骤 4 之后的几秒钟后才会执行。

您不能将异步函数放在这样的同步函数中,并期望它像“正常”函数一样工作。您需要设计代码来处理这种情况,包括调用 parseJSON 的代码 - 因为解析可能需要几秒钟,因此代码需要等待。如果您的应用程序有 GUI,那么如果您没有正确执行此操作,您的整个应用程序将挂起并冻结。

因此,当您使用异步编写时,您的整个应用程序必须设计为能够正确处理它。

【讨论】:

    猜你喜欢
    • 2014-01-15
    • 1970-01-01
    • 2014-03-05
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多