Ios 将数组传递给新的ViewController时EXC_访问错误
我正在从webservice(汽车数据)加载一些XML,创建一些汽车对象,并希望在TableViewController中显示它们 当用户选择了开始和目标位置时,我将对webservice进行异步调用,显示活动指示器,并在加载数据后立即转到新视图。所以我有这样的想法: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
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