BAD_EXC_ACCESS 用于在解除分配时尝试加载视图控制器

Posted

技术标签:

【中文标题】BAD_EXC_ACCESS 用于在解除分配时尝试加载视图控制器【英文标题】:BAD_EXC_ACCESS for attempting to load view controller while deallocating 【发布时间】:2016-09-04 22:11:19 【问题描述】:

我在网上收到了 BAD_EXC_ACCESS。原因是“不允许在解除分配时尝试加载视图控制器的视图,并且可能导致未定义的行为”。

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
                
            
        
    

【问题讨论】:

在 viewDidLoad @LeoDabus 中调用的我的 locationManager 中 没有区别@LeoDabus 在任何函数@LeoDabus之外的类的顶部 您没有显示足够的代码来诊断此问题。您需要显示这些调用的位置和方式、视图控制器的生命周期和位置管理器的生命周期。 发生这种情况的一个常见原因是您对相关视图控制器的引用较弱或仅限本地。所以它的引用计数在你期望它之前就变为零了,也许是在它在屏幕上转换的时候。您可能需要提升对强大、持久(类级别)属性的引用。 【参考方案1】:

performQuery 的完成块“必须能够在应用程序的任何线程上运行”(如文档中所述)。你调用 addOverlay 这是一个 UI 函数,在主队列上调用了这么多。您需要将此方法分派到主队列。

旁注,与问题无关:for(var i = 0; i&lt;records.count; i += 1) 写成for record in records 要好得多。不推荐使用 C 样式语法。

【讨论】:

以上是关于BAD_EXC_ACCESS 用于在解除分配时尝试加载视图控制器的主要内容,如果未能解决你的问题,请参考以下文章

尝试在解除分配时加载视图控制器的视图。核心聚焦

不允许在解除分配时尝试加载视图控制器的视图,这可能会导致未定义的行为

[myArray addObject:[[objcBlock copy] autorelease]] 在解除分配数组时崩溃

如何解除分配 CCLayer

watchOS 6 WKInterfaceImage 在解除分配时崩溃

删除、释放还是解除分配?