Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/117.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 将数组传递给新的ViewController时EXC_访问错误_Ios_Objective C_Swift_Swift2_Exc Bad Access - Fatal编程技术网

Ios 将数组传递给新的ViewController时EXC_访问错误

Ios 将数组传递给新的ViewController时EXC_访问错误,ios,objective-c,swift,swift2,exc-bad-access,Ios,Objective C,Swift,Swift2,Exc Bad Access,我正在从webservice(汽车数据)加载一些XML,创建一些汽车对象,并希望在TableViewController中显示它们 当用户选择了开始和目标位置时,我将对webservice进行异步调用,显示活动指示器,并在加载数据后立即转到新视图。所以我有这样的想法: class NewReservationViewController : UIViewController { @IBAction func searchCarsClicked(sender: UIBarButto

我正在从webservice(汽车数据)加载一些XML,创建一些汽车对象,并希望在TableViewController中显示它们

当用户选择了开始和目标位置时,我将对webservice进行异步调用,显示活动指示器,并在加载数据后立即转到新视图。所以我有这样的想法:

 class NewReservationViewController : UIViewController {
       @IBAction func searchCarsClicked(sender: UIBarButtonItem) {

            //show load cars activity indicator
            loadingCarsActivityIndicator.startAnimating()

            //load available cars from webservice asyncronously
           DataManager.getAvailableCars([...parameter list...], carsLoadedCallback: carsLoaded)


        }

        func carsLoaded(loadedCars: [Car]) {
            //dismiss the waiting widget
            //trigger the segue and advance to the next screen

            loadingCarsActivityIndicator.stopAnimating()
            print("stopped cars loading activity indicator")
            print("cars loaded callback called")
            print("loaded \(loadedCars.count) distinct cars")

            self.cars = loadedCars
            performSegueWithIdentifier("showAvailableCars", sender: self)

        }


    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        if segue.identifier == "showAvailableCars" {

            let carTableViewController = segue.destinationViewController as! CarTableViewController
            carTableViewController.cars = self.cars
            presentViewController(carTableViewController, animated: false, completion: nil)

        }
    }
}






class DataManager {


   class func getAvailableCars([...parameter list...], carsLoadedCallback: ([Car]) -> Void){
       Webservice.getAvailability([...parameter list...], completionHandler: { (data, response, error) in


           //parse xml
           //in the end I get an Array of Car objects


           var cars: [Car] = ...

           carsLoadedCallback(cars)

        })}
   }
}
当我用我在CarTableViewController类中创建的一些DummyData填充TableView时,它可以正常工作。但是,当我尝试将汽车阵列传递给TableViewController时,我得到一个EXC_BAD_ACCESS code=2异常。据我所知,这是一种内存异常,通常由损坏的指针引起。所以我猜我在静态数据管理器类中创建的car数组在我调用的静态方法中被销毁了。但是我不确定,因为自动引用计数应该可以避免这种情况

表视图甚至显示数据,但随后会立即因EXC_BAD_访问异常而崩溃。我试图在XCode的“断点”选项卡中设置一个常规断点,但没有得到关于应用程序崩溃原因的合理错误消息

你知道为什么会这样吗。如何获得更好的错误消息?
提前感谢您的帮助。

首先检查此功能:

func carsLoaded(loadedCars: [Car])
它作为回调返回-它运行的是哪个线程?主回合还是后回合? 你应该调用主线程

dispatch_async(dispatch_get_main_queue(), {
  performSegueWithIdentifier("showAvailableCars", sender: self)
})
如果没有帮助-提供行,它在调试器中的中断位置,以便我可以提供帮助并查看更多信息

UPD:没注意到,你为什么要做手工演示

presentViewController(carTableViewController, animated: false, completion: nil)

您的segue自动显示视图控制器,您可以在情节提要中更改其样式(模式、推送)。

我可以看到两个潜在问题。首先,您是从一个可能不在主线程上的方法触发segue的,您需要确保这是在主线程上完成的。另一个问题是,在prepare for segue中,您正在展开新的ViewController而没有检查它,因此请尝试以下操作:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

    if segue.identifier == "showAvailableCars" {

        if let carTableViewController = segue.destinationViewController as? CarTableViewController {
            carTableViewController.cars = self.cars
            presentViewController(carTableViewController, animated: false, completion: nil)
        }
    }
}

正如您所说,表视图显示数据,然后立即崩溃,我认为问题出在您的CarTableViewController中。您可以检查的一件事是,当您的单元格被渲染时,如果您试图从汽车对象访问一些空信息

不幸的是,当我这样做时,应用程序仍然崩溃。我的问题是,我没有得到一个合理的错误消息。我只看到AppDelegate和一条红色错误消息,带有EXC_BAD_访问权限。因此,我看不到它在调试器中中断的位置。将断点设置为以下行:
loadingCarsActivityIndicator.stopAnimating()
self.cars=loadedCars
performsgueWithIdentifier(“showAvailableCars”,sender:self)
重写函数准备过程(segue:UIStoryboardSegue,sender:AnyObject?
)。它停在哪里?哪里没有?它会在每个断点上停止。但是我注意到了一些奇怪的事情。如果我尝试使用dispatch\u async停止主线程上的活动指示符,即使在语句执行之后,它仍然会继续。这是什么?`presentViewController(carTableViewController,动画:false,完成:nil)`删除此行。你的segue显示了一个视图控制器,你再手动一次。是的,在这种情况下我肯定应该使用if-let。应用程序仍然崩溃。然而,如果我在主线程上调用Webservice,应用程序不会冻结吗?那么它将是一个同步调用。你认为我的一般做法如何?有没有一个更干净、更不容易出错的解决方案,这样我就不会遇到线程问题?你不需要在主线程上调用API,你需要在主线程上调用performsgue