swift refresh control致命错误:在展开Optional值时意外发现nil

时间:2014-09-19 15:26:25

标签: swift xcode6

我正在使用tableview控制器并尝试添加拉取刷新功能,但是当我在iPhone 5中测试pull to refresh功能时解开一个Optional值错误时我意外地发现了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.
    }
    */

}

1 个答案:

答案 0 :(得分:1)

在此行中,您的数据对象为零。

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中,可选值表示它可能为零。如果您没有从可选项中获取实际值,那么您的代码将无法编译。如果值不是nil,则上面的模式只会执行代码。