Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/98.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 视图控制器之间传递数据的差异_Ios_Json_Swift - Fatal编程技术网

Ios 视图控制器之间传递数据的差异

Ios 视图控制器之间传递数据的差异,ios,json,swift,Ios,Json,Swift,我正在尝试在第一个ViewController和第二个ViewController之间传递数据。我在ViewController的顶部有两个变量,它们被初始化为空。然后获取parse JSON数据,并将这两个变量的值设置为已解析的临时JSON变量。然后在prepareforSegue函数中,使SecondViewController的变量等于我的第一个ViewController中的前两个变量。由于某些原因,传递的变量仅在变量为空时传递。我不确定我是否讲得通,但以下是我的代码: class Vi

我正在尝试在第一个ViewController和第二个ViewController之间传递数据。我在ViewController的顶部有两个变量,它们被初始化为空。然后获取parse JSON数据,并将这两个变量的值设置为已解析的临时JSON变量。然后在prepareforSegue函数中,使SecondViewController的变量等于我的第一个ViewController中的前两个变量。由于某些原因,传递的变量仅在变量为空时传递。我不确定我是否讲得通,但以下是我的代码:

class ViewController: UIViewController {

var stockSymbol = String()
var stockPrice = String()

@IBOutlet weak var textField: UITextField!

@IBAction func buttonPressed(sender: AnyObject) {

    let requestURL: NSURL = NSURL(string: "https://finance.yahoo.com/webservice/v1/symbols/\(textField.text!)/quote?format=json")!
    let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)
    let session = NSURLSession.sharedSession()
    let task = session.dataTaskWithRequest(urlRequest) {
        (data, response, error) -> Void in

        let httpResponse = response as! NSHTTPURLResponse
        let statusCode = httpResponse.statusCode

        if (statusCode == 200) {
            print("Everyone is fine, file downloaded successfully.")

            do {

                let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments)

                if let resources = json["list"]?!["resources"] as? [[String:AnyObject]] {
                    if let fields = resources[0]["resource"]?["fields"] as? [String:String], price = fields["price"], symbol = fields["symbol"] {

                        self.stockSymbol = symbol
                        self.stockPrice = price

                        print(self.stockSymbol, self.stockPrice)
                    } 
                }

            } catch {
                print("Error with Json: \(error)")

                //end catch
            }

        } //end if status code == 200
    } //end task


    task.resume()

}

override func viewDidLoad() {
    super.viewDidLoad()

    //var test:String

}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if (segue.identifier == "searchResults") {

        print("working \(self.stockPrice)")
        let secondVC = segue.destinationViewController as! SecondViewController;
        secondVC.passedSymbol = self.stockSymbol
        secondVC.passedPrice = self.stockPrice
        print(secondVC.passedSymbol)



    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


}
基本上,我希望股票价格和符号被转移到我的第二个视图控制器的变量,但它似乎不起作用

第二视图控制器的代码:

class SecondViewController: UIViewController {

var passedSymbol: String!
var passedPrice: String!

@IBOutlet weak var symbol: UILabel!

@IBOutlet weak var price: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

    print("passed \(passedSymbol)")
    print("second view")
    dispatch_async(dispatch_get_main_queue()) {
    self.symbol.text = self.passedSymbol
    self.price.text = self.passedPrice

    }

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


}
将“aapl”放入searchField时输出语句

working 

passed 
second view
Everyone is fine, file downloaded successfully.
AAPL 100.529999

原因应该是,当您转到第二个viewcontroller时,您没有获得第一个viewcontroller中的数据。dataTaskWithRequest是一个异步函数,这意味着它在另一个线程而不是主ui线程上运行。您可以等待,直到在第一个viewcontroller中获得数据,然后调用segue。控制台上的打印信息可能会让您感到困惑,好像您已经获得了数据,但实际上它可能是在调用segue后发生的,并导致没有数据传递。

原因应该是,当您转到第二个viewcontroller时,您没有在第一个viewcontroller中获得数据。dataTaskWithRequest是一个异步函数,这意味着它在另一个线程而不是主ui线程上运行。您可以等待,直到在第一个viewcontroller中获得数据,然后调用segue。控制台上的打印信息可能会让您感到困惑,好像您已经获得了数据,但实际上,它可能在调用segue后发生,导致没有数据传递。

首先,不要这样做:

var stockSymbol = String()
var stockPrice = String()
这是一个坏习惯,使编译器不再抱怨未初始化的变量,而完全忽略了Swift中optionals的功能

相反,要这样做:

var stockSymbol:String!
var stockPrice:String!
这将确保在尝试使用变量而不设置值时出现异常

现在,您得到空值的原因(或者如果您做了我建议的更改,将得到异常)是当按下按钮时启动异步数据获取,但立即启动segue,大概是因为您有一个与按钮以及
touchUpInside
处理程序关联的操作

您需要删除动作序列并通过ctrl键从场景顶部的黄色
视图控制器
图标拖动到目标视图控制器来创建编程序列,并像往常一样为新序列指定标识符

然后,您可以更改
按钮pressed
函数,以便在检索到数据后调用segue

@IBAction func buttonPressed(sender: AnyObject) {

    let requestURL: NSURL = NSURL(string: "https://finance.yahoo.com/webservice/v1/symbols/\(textField.text!)/quote?format=json")!
    let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)
    let session = NSURLSession.sharedSession()
    let task = session.dataTaskWithRequest(urlRequest) {
        (data, response, error) -> Void in

        let httpResponse = response as! NSHTTPURLResponse
        let statusCode = httpResponse.statusCode

        if (statusCode == 200) {
            print("Everyone is fine, file downloaded successfully.")

            do {

                let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments)

                if let resources = json["list"]?!["resources"] as? [[String:AnyObject]] {
                    if let fields = resources[0]["resource"]?["fields"] as? [String:String], price = fields["price"], symbol = fields["symbol"] {

                        self.stockSymbol = symbol
                        self.stockPrice = price

                        print(self.stockSymbol, self.stockPrice)
                        dispatch_async(dispatch_get_main_queue(), {
                            self.performSegueWithIdentifier("searchResults",sender:sender)
                        })
                    } 
                }

            } catch {
                print("Error with Json: \(error)")

                //end catch
            }

        } //end if status code == 200
    } //end task


    task.resume()

}
首先,不要这样做:

var stockSymbol = String()
var stockPrice = String()
这是一个坏习惯,使编译器不再抱怨未初始化的变量,而完全忽略了Swift中optionals的功能

相反,要这样做:

var stockSymbol:String!
var stockPrice:String!
这将确保在尝试使用变量而不设置值时出现异常

现在,您得到空值的原因(或者如果您做了我建议的更改,将得到异常)是当按下按钮时启动异步数据获取,但立即启动segue,大概是因为您有一个与按钮以及
touchUpInside
处理程序关联的操作

您需要删除动作序列并通过ctrl键从场景顶部的黄色
视图控制器
图标拖动到目标视图控制器来创建编程序列,并像往常一样为新序列指定标识符

然后,您可以更改
按钮pressed
函数,以便在检索到数据后调用segue

@IBAction func buttonPressed(sender: AnyObject) {

    let requestURL: NSURL = NSURL(string: "https://finance.yahoo.com/webservice/v1/symbols/\(textField.text!)/quote?format=json")!
    let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)
    let session = NSURLSession.sharedSession()
    let task = session.dataTaskWithRequest(urlRequest) {
        (data, response, error) -> Void in

        let httpResponse = response as! NSHTTPURLResponse
        let statusCode = httpResponse.statusCode

        if (statusCode == 200) {
            print("Everyone is fine, file downloaded successfully.")

            do {

                let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments)

                if let resources = json["list"]?!["resources"] as? [[String:AnyObject]] {
                    if let fields = resources[0]["resource"]?["fields"] as? [String:String], price = fields["price"], symbol = fields["symbol"] {

                        self.stockSymbol = symbol
                        self.stockPrice = price

                        print(self.stockSymbol, self.stockPrice)
                        dispatch_async(dispatch_get_main_queue(), {
                            self.performSegueWithIdentifier("searchResults",sender:sender)
                        })
                    } 
                }

            } catch {
                print("Error with Json: \(error)")

                //end catch
            }

        } //end if status code == 200
    } //end task


    task.resume()

}

请显示
SecondViewController
的代码以及任何打印语句的输出。请显示
SecondViewController
的代码以及任何打印语句的输出。删除异步是什么意思?它本身是异步的。删除异步是什么意思?它本身是异步的。