func drawpolyline() { // Parsing GeoJsON can be cpu intensive,do it on a background thread dispatchQueue.global(qos: .background).async { // Get the path for example.geoJson in the app's bundle let JsonPath = Bundle.main.path(forResource: "KMLMAPNew",ofType: "Json") let JsonData = NSData(contentsOffile: JsonPath!) do { // Load and serialize the GeoJsON into a dictionary filled with properly-typed objects guard let JsonDict = try JsONSerialization.JsonObject(with: JsonData! as Data,options: []) as? Dictionary<String,AnyObject>,let features = JsonDict["features"] as? Array<AnyObject> else{return} for feature in features { guard let feature = feature as? Dictionary<String,let geometry = feature["geometry"] as? Dictionary<String,AnyObject> else{ continue } if geometry["type"] as? String == "linestring" { // Create an array to hold the formatted coordinates for our line var coordinates: [CLLocationCoordinate2D] = [] if let locations = geometry["coordinates"] as? Array<AnyObject> { // Iterate over line coordinates,stored in GeoJsON as many lng,lat arrays for location in locations { // Make a CLLocationCoordinate2D with the lat,lng if let location = location as? Array<AnyObject>{ let coordinate = CLLocationCoordinate2DMake(location[1].doubleValue,location[0].doubleValue) // Add coordinate to coordinates array coordinates.append(coordinate) } } } let line = MGLpolyline(coordinates: &coordinates,count: UInt(coordinates.count)) // Optionally set the Title of the polyline,which can be used for: // - Callout vIEw // - Object IDentification line.Title = "Crema to Council Crest" // Add the annotation on the main thread dispatchQueue.main.async { // UNowned reference to self to prevent retain cycle [uNowned self] in self.mapBoxVIEw.addAnnotation(line) } } } } catch { print("GeoJsON parsing Failed") } }}
编辑:: @ Alessandro Ornano和@fragilecat非常感谢.但这些解决方案仍然无法解决iPad终止应用的问题.我认为很难改变当前的代码以使其正常工作,因为数据太大了.我想我需要另一种适用于大数据的解决方案.就像将数组分块到小数组中一样,然后通过队列加载它们.但我不知道如何开始:(
我向MapBox的支持团队发送电子邮件,询问建议.
解决方法 这里的问题与有效的内存管理有关.您正在通过Json文件加载大量数据.您意识到您需要在后台队列(线程)上完成大部分工作,但问题是如何通过dispatchQueue.main.async函数更新UI.在当前版本的drawpolyline()方法中,在给定第一个循环中的对象数量的情况下,您将在后台队列和主队列之间切换66234次.您还创建了相同数量的CLLocationCoordinate2D数组.这导致巨大的内存占用.您没有提到有关如何渲染线条的任何要求.因此,如果我们重新构建drawpolyline()方法以使用CLLocationCoordinate2D数组的实例变量,那么我们只使用一个,然后在更新UI之前处理所有Json文件.内存使用量下降到更可管理的664.6 MB.
当然,渲染可能并不完全符合您的要求,如果是这种情况,您可能希望将CLLocationCoordinate2D数组重组为更合适的数据结构.
下面是您的VIEwController类,其中重写的drawpolyline()为drawpolyline2()
import UIKitimport MapBoxclass VIEwController: UIVIEwController,MGLMapVIEwDelegate {@IBOutlet var mapBoxVIEw: MGLMapVIEw!fileprivate var coordinates = [[CLLocationCoordinate2D]]()fileprivate var JsonData: NSData?overrIDe func vIEwDIDLoad() { super.vIEwDIDLoad() // Do any additional setup after loading the vIEw,typically from a nib. mapBoxVIEw = MGLMapVIEw(frame: vIEw.bounds) mapBoxVIEw.autoresizingMask = [.flexibleWIDth,.flexibleHeight] // mapBoxVIEw.setCenter(CLLocationCoordinate2D(latitude: 45.5076,longitude: -122.6736),// zoomLevel: 11,animated: false) mapBoxVIEw.setCenter(CLLocationCoordinate2D(latitude: 1.290270,longitude: 103.851959),zoomLevel: 11,animated: false) vIEw.addSubvIEw(self.mapBoxVIEw) mapBoxVIEw.delegate = self mapBoxVIEw.allowsZooming = true drawpolyline2() //newWay()}overrIDe func dIDReceiveMemoryWarning() { super.dIDReceiveMemoryWarning() // dispose of any resources that can be recreated.}func drawpolyline2() { dispatchQueue.global(qos: .background).async { if let path = Bundle.main.path(forResource: "KMLMAPNew",ofType: "Json") { let fileURL = URL(fileURLWithPath: path) if let data = try? Data(contentsOf: fileURL) { do { let dictionary = try JsONSerialization.JsonObject(with: data as Data,AnyObject> if let features = dictionary?["features"] as? Array<AnyObject> { print("** START **") for feature in features { guard let feature = feature as? Dictionary<String,AnyObject> else { continue } if geometry["type"] as? String == "linestring" { // Create an array to hold the formatted coordinates for our line if let locations = geometry["coordinates"] as? Array<AnyObject> { // Iterate over line coordinates,lat arrays var featureCoordinates = [CLLocationCoordinate2D]() for location in locations { // Make a CLLocationCoordinate2D with the lat,lng if let location = location as? Array<AnyObject>{ let coordinate = CLLocationCoordinate2DMake(location[1].doubleValue,location[0].doubleValue) // Add coordinate to coordinates array featureCoordinates.append(coordinate) } } // Uncomment if you need to store for later use. //self.coordinates.append(featureCoordinates) dispatchQueue.main.async { let line = MGLpolyline(coordinates: &featureCoordinates,count: UInt(featureCoordinates.count)) // Optionally set the Title of the polyline,which can be used for: // - Callout vIEw // - Object IDentification line.Title = "Crema to Council Crest" self.mapBoxVIEw.addAnnotation(line) } } } } print("** FINISH **") } } catch { print("GeoJsON parsing Failed") } } } }}func drawSmallListObj(List: [Dictionary<String,AnyObject>]){ for obj in List{ // print(obj) if let feature = obj as? Dictionary<String,AnyObject> { if let geometry = feature["geometry"] as? Dictionary<String,AnyObject> { if geometry["type"] as? String == "linestring" { // Create an array to hold the formatted coordinates for our line var coordinates: [CLLocationCoordinate2D] = [] if let locations = geometry["coordinates"] as? Array<AnyObject> { // Iterate over line coordinates,which can be used for: // - Callout vIEw // - Object IDentification line.Title = "Crema to Council Crest" // Add the annotation on the main thread dispatchQueue.main.async { // UNowned reference to self to prevent retain cycle [uNowned self] in self.mapBoxVIEw.addAnnotation(line) } } } } }}func mapVIEw(_ mapVIEw: MGLMapVIEw,AlphaForShapeAnnotation annotation: MGLShape) -> CGfloat { // Set the Alpha for all shape annotations to 1 (full opacity) return 1}func mapVIEw(_ mapVIEw: MGLMapVIEw,linewidthForpolylineAnnotation annotation: MGLpolyline) -> CGfloat { // Set the line wIDth for polyline annotations return 2.0}func mapVIEw(_ mapVIEw: MGLMapVIEw,strokecolorForShapeAnnotation annotation: MGLShape) -> UIcolor { // Give our polyline a unique color by checking for its `Title` property if (annotation.Title == "Crema to Council Crest" && annotation is MGLpolyline) { // MapBox cyan return UIcolor(red: 59/255,green:178/255,blue:208/255,Alpha:1) } else { return UIcolor.red }}}总结
以上是内存溢出为你收集整理的ios – 来自调试器的消息:由于内存问题而终止全部内容,希望文章能够帮你解决ios – 来自调试器的消息:由于内存问题而终止所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)