关于我的应用程序的一些背景:我正在绘制地图。当用户移动地图时,我将执行数据库查询。我首先执行rTree查询,以查找将在当前视口中绘制的要素。获得这些ID后,我将执行第二次数据库查询,以从数据库中提取要素(geojson)。我进行快速检查以查看是否已经绘制了该项目,否则,我进行了addChild
来在地图上渲染地图项。我想通过GCD在后台查找这些数据库,以便用户可以平滑地移动地图。我已经实现了这一点,但是内存使用量迅速增长到了1gb,而如果我在主线程中完成所有工作,则它将占用250mb(我可以接受)。我假设由于使用闭包而未清除某些内容。感谢您对导致内存泄漏的原因有深入的了解。
public func drawItemsInBox(boundingBox: [Double]) {
DispatchQueue.global(qos: .background).async { [weak self] in
guard let self = self else {
return
}
var drawItems: [Int64] = []
let table = Table("LNDARE_XS")
let tableRTree = Table("LNDARE_XS_virtual")
let coords = Expression<String?>("coords")
let foid = Expression<String>("foid")
let rTree = Expression<Int64>("rTree")
let minX = Expression<Double>("minX")
let maxX = Expression<Double>("maxX")
let minY = Expression<Double>("minY")
let maxY = Expression<Double>("maxY")
let id = Expression<Int64>("id")
// find all the features to draw via an rTree query
for row in try! self.db.prepare(tableRTree.filter(maxX >= boundingBox[0] && minX <= boundingBox[1] && maxY >= boundingBox[2] && minY <= boundingBox[3])) {
drawItems.append(row[id])
}
do {
// get all the features geojson data
let query = table.filter(drawItems.contains(rTree))
for row in try self.db.prepare(query) {
// skip drawing if the feature already exists on the map
if self.featureTracking["LNDARE_XS"]?[Int64(row[foid])!] == nil {
// convert the database string to an array of coords
var toBeRendered:[CGPoint] = []
let coordsArray = row[coords]!.components(separatedBy: ",")
for i in 0...(coordsArray.count / 2) - 1 {
toBeRendered.append(CGPoint(x: (Double(coordsArray[i*2])!), y: (Double(coordsArray[(i*2)+1])!)))
}
let linearShapeNode = SKShapeNode(points: &toBeRendered, count: toBeRendered.count)
linearShapeNode.position = CGPoint(x: self.frame.midX, y: self.frame.midY)
linearShapeNode.lineWidth = 0
linearShapeNode.fillColor = NSColor.black
// append the featureId for tracking and call addChild to draw
self.scaleLayer.addChild(linearShapeNode)
self.featureTracking["LNDARE_XS"]?[Int64(row[foid])!] = linearShapeNode
}
}
} catch {
// catch
}
}
}
答案 0 :(得分:1)
也许更改toBeRendered
可以保存一些内容:
var toBeRendered:[CGPoint] = []
for row in try self.db.prepare(query) {
// skip drawing if the feature already exists on the map
if self.featureTracking["LNDARE_XS"]?[Int64(row[foid])!] == nil {
// convert the database string to an array of coords
toBeRendered.removeAll()
let coordsArray = row[coords]!.components(separatedBy: ",")
for i in 0...(coordsArray.count / 2) - 1 {
toBeRendered.append(CGPoint(x: (Double(coordsArray[i*2])!), y: (Double(coordsArray[(i*2)+1])!)))
}
答案 1 :(得分:0)
由于您不在主线程上,因此可能尝试使用自动释放池
public func drawItemsInBox(boundingBox: [Double]) {
DispatchQueue.global(qos: .background).async { [weak self] in
guard let self = self else {
return
}
var drawItems: [Int64] = []
let table = Table("LNDARE_XS")
let tableRTree = Table("LNDARE_XS_virtual")
let coords = Expression<String?>("coords")
let foid = Expression<String>("foid")
let rTree = Expression<Int64>("rTree")
let minX = Expression<Double>("minX")
let maxX = Expression<Double>("maxX")
let minY = Expression<Double>("minY")
let maxY = Expression<Double>("maxY")
let id = Expression<Int64>("id")
// find all the features to draw via an rTree query
for row in try! self.db.prepare(tableRTree.filter(maxX >= boundingBox[0] && minX <= boundingBox[1] && maxY >= boundingBox[2] && minY <= boundingBox[3])) {
drawItems.append(row[id])
}
do {
// get all the features geojson data
let query = table.filter(drawItems.contains(rTree))
for row in try self.db.prepare(query) {
autoreleasepool{
// skip drawing if the feature already exists on the map
if self.featureTracking["LNDARE_XS"]?[Int64(row[foid])!] == nil {
// convert the database string to an array of coords
var toBeRendered:[CGPoint] = []
let coordsArray = row[coords]!.components(separatedBy: ",")
for i in 0...(coordsArray.count / 2) - 1 {
toBeRendered.append(CGPoint(x: (Double(coordsArray[i*2])!), y: (Double(coordsArray[(i*2)+1])!)))
}
let linearShapeNode = SKShapeNode(points: &toBeRendered, count: toBeRendered.count)
linearShapeNode.position = CGPoint(x: self.frame.midX, y: self.frame.midY)
linearShapeNode.lineWidth = 0
linearShapeNode.fillColor = NSColor.black
// append the featureId for tracking and call addChild to draw
self.scaleLayer.addChild(linearShapeNode)
self.featureTracking["LNDARE_XS"]?[Int64(row[foid])!] = linearShapeNode
}
}
}
} catch {
// catch
}
}
}