来自调试器的消息:由于内存问题而终止 [英] Message from debugger: Terminated due to memory issue

查看:124
本文介绍了来自调试器的消息:由于内存问题而终止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序正在处理Geojson文件.我使用 MapBox SDK MGLPolyline添加到地图中.但是问题是我的文件太大,导致应用程序崩溃并出现错误:Message from debugger: Terminated due to memory issue.我在第一个循环中遇到了 66234 对象.我试图将数组分块为新数组,但未成功.请帮助我解决问题.这是我在地图上绘制的代码,这是我的在github上测试项目使用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, AnyObject>, 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的支持团队发送电子邮件,征求建议.

解决方案

从创建占用大量内存的应用程序中学到的一件事是,如果这些循环很长,则每次在循环内创建变量时都必须使用autoreleasepool. /p>

查看您的所有代码并转换类似的内容

func loopALot() {
    for _ in 0 ..< 5000 {
        let image = NSImage(contentsOfFile: filename)
    }
}

进入

func loopALot() {
    for _ in 0 ..< 5000 {
      autoreleasepool {
        let image = NSImage(contentsOfFile: filename)
      }
    }
}

查看各种循环forwhile等.

这将迫使iOS在每次循环结束时释放变量及其对应的内存使用量,而不是保留变量及其内存使用量直到函数结束.这将大大减少您的内存使用量.

My app working with Geojson file. I use MapBox SDK to add MGLPolyline to map. But the problem is my file too large, so that the app crash and got the error: Message from debugger: Terminated due to memory issue. I faced with 66234 objects at first loop. I tried to chunk the array to new array but not success. Please help me to solve the prolem. Here is my code for draw on map and here is my test project on github use Xcode 8.1 If have any different 3rd party which can solve my prolems is welcome too:

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, AnyObject>, 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")
        }
    }
}

EDIT::@Alessandro Ornano and @fragilecat thanks so much. But those solutions still cannot solve the terminate of the app on iPad. I think it so hard to change the current code to get it to work properly, because the data is so large. I think I will need another solution that works with big data. Like chunking the array into the small arrays then loading them by queue. But I don't know how to start :(

I send an email to the support team at MapBox, asking for suggestions.

解决方案

One thing I have learnt from creating memory intensive apps is that you have to use autoreleasepool every time you create variables inside loops, if these loops are long

Review all your code and transform things like

func loopALot() {
    for _ in 0 ..< 5000 {
        let image = NSImage(contentsOfFile: filename)
    }
}

into

func loopALot() {
    for _ in 0 ..< 5000 {
      autoreleasepool {
        let image = NSImage(contentsOfFile: filename)
      }
    }
}

Review all kinds of loops for, while, etc.

This will force of iOS to release the variable and its correspondent memory usage at the end of every turn of the loop, instead of holding the variable and its memory usage until the function ends. That will reduce dramatically your memory usage.

这篇关于来自调试器的消息:由于内存问题而终止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆