ios – 来自调试器的消息:由于内存问题而终止

ios – 来自调试器的消息:由于内存问题而终止,第1张

概述我的应用程序使用Geojson文件.我使用 MapBox SDK将MGLPolyline添加到地图中.但问题是我的文件太大,以至于应用程序崩溃并收到错误:来自调试器的消息:由于内存问题而终止.我在第一次循环时面对66234个对象.我试图将数组块化为新数组,但没有成功.请帮我解决问题.这是我在地图上绘制的代码,这里是我的 test project on github use Xcode 8.1如果有 我的应用程序使用GeoJson文件.我使用 MapBox SDK将MGLpolyline添加到地图中.但问题是我的文件太大,以至于应用程序崩溃并收到错误:来自调试器的消息:由于内存问题而终止.我在第一次循环时面对66234个对象.我试图将数组块化为新数组,但没有成功.请帮我解决问题.这是我在地图上绘制的代码,这里是我的 test project on github use Xcode 8.1如果有任何不同的第三方可以解决我的问题也欢迎:
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 – 来自调试器的消息:由于内存问题而终止所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1099102.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-28
下一篇 2022-05-28

发表评论

登录后才能评论

评论列表(0条)

保存