0

I'm getting a BAD_EXC_ACCESS on line . The reason is "Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior".

func drawLocations(loc: CLLocation)
    {
        let center = CLLocationCoordinate2D(latitude: loc.coordinate.latitude, longitude: loc.coordinate.longitude)
        let lat: CLLocationDegrees = center.latitude
        let long: CLLocationDegrees = center.longitude
        var points = [CLLocationCoordinate2DMake(lat,long),CLLocationCoordinate2DMake(lat,long),CLLocationCoordinate2DMake(lat,long),CLLocationCoordinate2DMake(lat,long)]
        let polygon = MKPolygon(coordinates: &points, count: points.count)
        mapView.addOverlay(polygon)//where I get error
    }
func loadLocation(completion: (error:NSError?, records:[CKRecord]?) -> Void)
    {
        let query = CKQuery(recordType: "Location", predicate: NSPredicate(value: true))
        CKContainer.defaultContainer().publicCloudDatabase.performQuery(query, inZoneWithID: nil){
            (records, error) in
            if error != nil {
                print("error fetching locations: \(error)")
                completion(error: error, records: nil)
            } else {
                print("found locations: \(records)")
                print("found locations")
                completion(error: nil, records: records)
                guard let records = records else {
                    return
                }
                for(var i = 0; i<records.count; i += 1)
                {
                    self.drawLocations(records[i]["location"] as! CLLocation)//where I call function
                }
            }
        }
    }
Steve
  • 1,121
  • 1
  • 12
  • 32
  • In my locationManager that is called in viewDidLoad @LeoDabus – Steve Sep 04 '16 at 22:16
  • There's no difference @LeoDabus – Steve Sep 04 '16 at 22:19
  • top of the class outside any function @LeoDabus – Steve Sep 04 '16 at 22:27
  • You haven't shown enough code for this to be diagnosed. You need to show from where and how these are being called, the lifetime of your view controller and the lifetime of the location manager. – Gruntcakes Sep 04 '16 at 23:13
  • A common reason this happens is you have a weak or local-only reference to the view controller in question. So its reference count goes to zero before you expect it to, perhaps while it's transitioning on screen. You probably need to promote the reference to a strong, persistent (class-level) property. – BaseZen Sep 05 '16 at 00:01
  • @BaseZen I checked but no luck. There was no error until I tried to use a ckrecord for the location for the mapView overlay instead of a set location. – Steve Sep 05 '16 at 00:07
  • Have you accounted for threading issues e.g.: my answer here should be applicable (conceptually identical, superficially different): http://stackoverflow.com/questions/32292600/swift-performseguewithidentifier-not-working/32292706#32292706 – BaseZen Sep 05 '16 at 00:26

1 Answers1

1

The completion block of performQuery "must be capable of running on any thread of the app" (as described in the docs). You call addOverlay which is a UI function, and so much be called on the main queue. You need to dispatch this method to the main queue.

Side note, unrelated to the question: for(var i = 0; i<records.count; i += 1) is much better written as for record in records. The C-style syntax is deprecated.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610