EXC_BAD_ACCESS by passing the array to the new ViewController

advertisements

I'm loading some XML from a webservice (car data), create some car objects and would like to display them in a TableViewController.

When the user has selected start and destination location, I'm making an async call to the webservice, show an activity indicator and as soon as the data is loaded, I go to a new view. So I have something like this:

 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)

        })}
   }
}

When I populate the TableView with some DummyData I create within the CarTableViewController class, it works fine. However when I try to pass the car arrays to my TableViewController I get a EXC_BAD_ACCESS code = 2 exception. As far as I know this is some kind of Memory exception that is usually caused by a corrupt pointer. So I guess that the car array I created in my static DataManager class within the static method I called gets destroyed. However I'm not sure about that because automatic reference counting should avoid that.

The table view even displays the data but then immediately crashes with the EXC_BAD_ACCESS exception. I tried to set a general breakpoint in the XCode's breakpoints tab but however I don't get a reasonable error message on why the app crashes.

Do you have any ideas on why this happens. How can I get a better error message? Thanks for your help in advance.


First of all check this function:

func carsLoaded(loadedCars: [Car])

It is returned as callback - what thread is it running? main or backround? You should call on main thread

dispatch_async(dispatch_get_main_queue(), {
  performSegueWithIdentifier("showAvailableCars", sender: self)
})

If doesn't help - provide the line, where it breaks in debugger, so I can help and see more.

UPD: Didn't notice, why do you do manual present?

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

Your segue automatically shows view controller, you can change it's style (modal, push) in storyboard.