swift刷新控制致命错误:在展开可选值时意外发现nil



我正在使用tableview控制器并尝试添加pull刷新功能,但在iPhone 5中测试pull to refresh功能时,在打开可选值错误时意外发现nil。错误发生在connectionDidFinishLoading函数处。

    class FixtureTableTableViewController: UITableViewController,UITableViewDelegate,NSURLConnectionDelegate {
    var fixtures:[Fixture] = []
    var data = NSMutableData()
    var jsonResults:NSArray! = nil
       override func viewDidLoad() {
        println("view did load")
        super.viewDidLoad()
        connectToServer();
        self.refreshControl = UIRefreshControl()
        //self.refreshControl?.attributedTitle = NSAttributedString(string: "pull to refresh")
        self.refreshControl?.addTarget(self, action: Selector("refresh"), forControlEvents: UIControlEvents.ValueChanged)


        //self.fixtures = Fixture().listAll()
        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false
        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem()
    }
    func refresh(){
        println("refresh table")
        fixtures = []
        connectToServer()
        self.refreshControl?.endRefreshing()
    }
    func connectToServer(){
        println("connect to server")
        let plist = NSBundle.mainBundle().pathForResource("hijaukuningapp",ofType: "plist")
        let dict = NSDictionary(contentsOfFile: plist!)
        var serverURL = dict["serverURL"] as String
        println("server url (serverURL)")
        let urlPath:String = serverURL + "mobileFixture/list"
        println(urlPath)
        var url = NSURL(string: urlPath)
        var request = NSURLRequest(URL: url)
        var connect = NSURLConnection(request: request, delegate: self, startImmediately: true)
        connect.start()
    }
    func connection(connection: NSURLConnection, didReceiveData _data: NSData!){
        println("receivedata")
        data.appendData(_data)
        println("end append data")
    }
    func connectionDidFinishLoading(connection: NSURLConnection){
        println("finished loading data(data)")
        var err: NSError
        // throwing an error on the line below (can't figure out where the error message is)
        jsonResults = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSArray
        println(jsonResults)
        fixtures = Fixture().listAll(jsonResults)
        self.tableView.reloadData()
    }
    override func viewWillAppear(animated: Bool) {
        println("viewWillAppear")
        super.viewWillAppear(animated)

    }
    /*
    override func viewWillAppear(animated: Bool) {
        //startConnection();
        println(jsonResults)
        for result : AnyObject in jsonResults {
            //println(result)
            if let fixture = result as? Dictionary<String,AnyObject>{
                var fixtureID = fixture["day"]
                println(fixtureID)
                var monthNamne = fixture["monthname"]
                var tempFixture = Fixture()
                tempFixture.day = fixtureID as String
                tempFixture.month = monthNamne as String
                var f2 = Fixture()
                f2.homeTeam="KELANTAN"
                f2.awayTeam = "KEDAH"
                f2.venue = "STADIUM SULTAN MOHAMED, ALOR SETAR"
                f2.day = "13"
                f2.month = "OCT"
                f2.time = "2045"
                fixtures.append(f2)
                self.tableView.reloadData()
            }
            println(fixtures.count)
        }
    }
*/
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    // MARK: - Table view data source
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Potentially incomplete method implementation.
        // Return the number of sections.
        return 1
    }
    override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete method implementation.
        // Return the number of rows in the section.
        return fixtures.count
    }
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as FixtureTableViewCell
        cell.lblVenue.text = fixtures[indexPath.row].venue
        cell.lblHome.text = fixtures[indexPath.row].homeTeam.name
        cell.lblAway.text = fixtures[indexPath.row].awayTeam.name
        cell.lblDay.text = fixtures[indexPath.row].day
        cell.lblMonth.text = fixtures[indexPath.row].month
        cell.lblTime.text = fixtures[indexPath.row].time
        var code:String = fixtures[indexPath.row].homeTeam.code + ".png"
        var awayCode:String = fixtures[indexPath.row].awayTeam.code + ".png"
        cell.homeLogo.image = UIImage(named: code);
        cell.awayLogo.image = UIImage(named: awayCode)
        return cell
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        println("indexpat " )
            }
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
        println("prepare for sergues")
        var detailController:FixtureDetailViewController = segue.destinationViewController as FixtureDetailViewController
        var indexPath = self.tableView.indexPathForSelectedRow()
        detailController.fixture = fixtures[indexPath!.row]
    }

    /*
    // Override to support conditional editing of the table view.
    override func tableView(tableView: UITableView!, canEditRowAtIndexPath indexPath: NSIndexPath!) -> Bool {
        // Return NO if you do not want the specified item to be editable.
        return true
    }
    */
    /*
    // Override to support editing the table view.
    override func tableView(tableView: UITableView!, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath!) {
        if editingStyle == .Delete {
            // Delete the row from the data source
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        } else if editingStyle == .Insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }    
    }
    */
    /*
    // Override to support rearranging the table view.
    override func tableView(tableView: UITableView!, moveRowAtIndexPath fromIndexPath: NSIndexPath!, toIndexPath: NSIndexPath!) {
    }
    */
    /*
    // Override to support conditional rearranging of the table view.
    override func tableView(tableView: UITableView!, canMoveRowAtIndexPath indexPath: NSIndexPath!) -> Bool {
        // Return NO if you do not want the item to be re-orderable.
        return true
    }
    */
    /*
    // MARK: - Navigation
    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
        // Get the new view controller using [segue destinationViewController].
        // Pass the selected object to the new view controller.
    }
    */
}

在这一行中,您的数据对象为nil。

jsonResults = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSArray

通过以下操作修复:

if let d = data {
        //Only executed if data isn't nil
        jsonResults = NSJSONSerialization.JSONObjectWithData(d, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSArray
}

在swift中,可选值意味着它可以为零。如果您没有从可选项中获得实际值,那么您的代码将无法编译。上面的模式只会在值不为零的情况下执行代码。

最新更新