swift Xcode:在展开可选值(lldb)时意外发现nil



当我运行这段代码,更新标签(label和bLabel)完美。viewDidLoad运行完美,但当我按下freshButtonPressed Xcode显示错误。在self.aLabel.text = var1上展开可选值时意外发现nil(注释显示错误位置)。viewDidLoad的代码与freshButtonPressed相同。我无法解决这个问题。

我很感激。

import UIKit
class segView1ViewController: UIViewController {
@IBOutlet weak var dollarUSALabel: UILabel!
@IBOutlet weak var euroLabel: UILabel!

func refreshingData1() {
    println("refreshing ...")
    var dollar2 = ""
    var euro2 = ""
    var arzUrl = NSURL(string: "http://www.arzlive.com")
    if arzUrl != nil {
        let task2 = NSURLSession.sharedSession().dataTaskWithURL(arzUrl!, completionHandler: { (data, response, error) -> Void in
            var urlError = false
            if error == nil {
                //main code
                //parsing url contents
                var arzUrlContent = NSString(data: data, encoding: NSUTF8StringEncoding) as NSString!
                //println(arzUrlContent)

                /////////// Dollar
                var dollarTempArray = arzUrlContent.componentsSeparatedByString("s3_40 price">")
                //println(dollarTempArray[1])
                if dollarTempArray.count > 0 {
                    var dollarTempArray2 = dollarTempArray[1].componentsSeparatedByString("<td")
                    dollar2 = dollarTempArray2[0] as! String
                    //println(dollar)
                } else {
                    urlError = true
                }

                ////////// Euro
                var euroTempArray = arzUrlContent.componentsSeparatedByString("s3_41 price">")
                //println(euroTempArray[1])
                if euroTempArray.count > 0 {
                    var euroTempArray2 = euroTempArray[1].componentsSeparatedByString("<td")
                    euro2 = euroTempArray2[0] as! String
                    //println(euro)
                } else {
                    urlError = true
                }
                } else {
                //error handling for web task error
                urlError = true
            }
            dispatch_async(dispatch_get_main_queue()) {
                //checking error
                if urlError == true {
                    //run error func
                    self.showError()
                } else {
                    //update labels here
                    self.dollarUSALabel.text = dollar2
                    self.euroLabel.text = euro2

                }
            }
        })
        //resume task
        task2.resume()
    } else {
        // error handler 
        showError()
    }
    ////////end of func
}

    func showError() {    
        //some error handling code...
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        self.dollarUSALabel.text = "0"
        self.euroLabel.text = "0"
        var dollar = ""
        var euro = ""
        // arzlive url
    var arzUrl = NSURL(string: "http://www.arzlive.com")
    if arzUrl != nil {
        let task1 = NSURLSession.sharedSession().dataTaskWithURL(arzUrl!, completionHandler: { (data, response, error) -> Void in
            var urlError = false
            if error == nil {
                //main code
                //parsing url contents
                var arzUrlContent = NSString(data: data, encoding: NSUTF8StringEncoding) as NSString!
                //println(arzUrlContent)

                /////////// Dollar
                var dollarTempArray = arzUrlContent.componentsSeparatedByString("s3_40 price">")
                //println(dollarTempArray[1])
                if dollarTempArray.count > 0 {
                    var dollarTempArray2 = dollarTempArray[1].componentsSeparatedByString("<td")
                    dollar = dollarTempArray2[0] as! String
                    //println(dollar)
                } else {
                    urlError = true
                }

                ////////// Euro
                var euroTempArray = arzUrlContent.componentsSeparatedByString("s3_41 price">")
                //println(euroTempArray[1])
                if euroTempArray.count > 0 {
                    var euroTempArray2 = euroTempArray[1].componentsSeparatedByString("<td")
                    euro = euroTempArray2[0] as! String
                    //println(euro)
                } else {
                    urlError = true
                }

            } else {
                //error handling for web task error
                urlError = true
            }
            dispatch_async(dispatch_get_main_queue()) {
                //checking error
                if urlError == true {
                    //run error func
                    self.showError()
                } else {
                    //update labels here
                    self.dollarUSALabel.text = dollar
                    self.euroLabel.text = euro
                }
            }
        })
        //resume task
        task1.resume()
    } else {
        // error handler 
        showError()
    }
}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

运行项目。无法重现此问题。有两个问题:

——你的代码不能编译,因为没有在任何地方声明dollarTempArray。请提交一些可以编译的东西。

——你有一个数组索引逻辑错误,因为你正在检查计数是否至少为1,但然后索引第二个元素(在索引1,而不是索引0,你应该检查)

请提交一个版本,编译和理想的网站,提供的数据。虽然,我硬编码的值代替var1和var2和UI更新没有问题。

既然你的崩溃与你发布的代码不同步,我敢打赌你的环境中的其他东西也不同步。退出Xcode &iOS模拟器,返回,做一个干净的构建,验证你的Outlets,并发布你现在真正拥有的东西。

调用变量var12345既残忍又受虐,所以现在开始放弃这种做法,即使在测试代码中也是如此。对于这种公然违反良好惯例的行为,要提供帮助要困难得多。

**那天晚些时候**

我把它通过专业程序员解码,结果如下。你要做的事情并不复杂,也不需要很长时间。请注意风格、抽象、效率以及bug修复。我刚刚在iPhone 6上的Xcode 6.4/Swift 1.2/iOS模拟器中测试了这个。

import UIKit
class CurrencyViewController: UIViewController {
    @IBOutlet weak var dollarUSALabel: UILabel!
    @IBOutlet weak var euroLabel: UILabel!
    let dataURL = "http://www.arzlive.com"
    func refreshData() {
        println("refreshing ...")
        if let arzUrl = NSURL(string: dataURL) {
            let task2 = NSURLSession.sharedSession().dataTaskWithURL(arzUrl)
                { [unowned self]
                    (data, response, error) -> Void in
                    if let d = data, arzUrlContent = NSString(data: d, encoding: NSUTF8StringEncoding) {            
                        var dollar: String?
                        var euro: String?
                        let dollarTempArray = arzUrlContent.componentsSeparatedByString("s3_40 price">")
                        if dollarTempArray.count >= 2 {
                            let dollarTempArray2 = dollarTempArray[1].componentsSeparatedByString("<td")
                            dollar = dollarTempArray2[0] as? String
                        }
                        let euroTempArray = arzUrlContent.componentsSeparatedByString("s3_41 price">")
                        if euroTempArray.count >= 2 {
                            var euroTempArray2 = euroTempArray[1].componentsSeparatedByString("<td")
                            euro = euroTempArray2[0] as? String
                        }
                    }
                    dispatch_async(dispatch_get_main_queue()) {
                        self.dollarUSALabel.text = dollar ?? "Could not get dollars!"
                        self.euroLabel.text = euro ?? "Could not get euros!"
                    }
            }
            task2.resume() // START task ('resume' is misleading)
        }
        else {
            showError("Could not access (dataURL)")
        }
    } /* end of refreshData */
    /* TODO for you: Use UIAlertController to inform the user */
    func showError(message: String) {
        println(message)
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        refreshData()
    }
}

最新更新