我的应用程序(导航应用程序)的内存不断增长,直到iOS迟早杀死它。我能够在每秒触发的定时器目标函数中查明使用自定义DispatchQueue的问题。 (即,当导航计时器正在运行时,每秒触发一次并执行下面的updateUI
功能。)
这是viewcontroller的摘录:
class NavViewController: UIViewController, ... {
...
let processLocationUpdateQeue = DispatchQueue(label: "processLocationUpdateQeue", qos: .userInteractive)
var updateUITimer: Timer!
...
func startNav() {
...
DispatchQueue.main.async { [unowned self] (_) -> Void in
self.updateUITimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(NavViewController.updateUI), userInfo: nil, repeats: true)
}
...
}
func updateUI() {
let freeDrive = self.isFreeDrive ?? false
processLocationUpdateQeue.async { [unowned self] in
self.totalBreakTimeInclCurrentBreak = self.totalBreakTimeInSec
if !self.takingBreak {
if self.timeOfLastPositionUpdate != nil && self.timeOfLastPositionUpdate.secondsAgo() >= 90 {
// some code that's not being executed during my analyses of this problem
}
}
else {
self.totalBreakTimeInclCurrentBreak = self.totalBreakTimeInSec + Float((self.breakStartTime ?? Date()).secondsAgo())
if ((self.autoResumeSwitch != nil && self.autoResumeSwitch!.isOn) || self.autoResumeSwitch == nil) && self.breakStartCoordinate?.distance(from: lastKnownLocation.coordinate.toCLLocation()) > 100 {
// some code that's not being executed during my analyses of this problem
}
}
self.avgSpeedMperS = min(self.maxSpeedMperS,self.coveredDistanceInMeters/(Float(self.tripStartTime.secondsAgo())-self.totalBreakTimeInclCurrentBreak))
if freeDrive && UIApplication.shared.applicationState == .active {
// app is running in background for my analyses, so the code here doesn't get executed
}
}
}
}
当我使用Instruments分配工具运行我的应用程序时,我看到内存不断增长。大多数(实际上所有)增长都在非对象中,而堆栈跟踪指向updateUI
函数。看这个截图:
请注意在调用函数的步骤之后(上方)的跟踪步骤。它与DispatchQueue有关。
我现在已经分析了这两天,试了很多东西。这就是我现在所知道的:
processLocationUpdateQeue.async {}
中取出代码并在主队列上运行它。processLocationUpdateQeue.async {}
内的代码包装到autoreleasepool {}
并不帮助processLocationUpdateQeue = DispatchQueue(label: "processLocationUpdateQeue", qos: .userInteractive, attributes: [], autoreleaseFrequency: .workItem, target: nil)
(注意.workItem)并没有帮助。[unowned self]
所以保留周期不是问题(我认为)?? [weak self]
,同样的问题。DispatchQueue(label: "processLocationUpdateQeue", qos: .userInteractive).async {}
而不是使用类processLocationUpdateQeue
,同样的问题我做错了什么?
更新 所以,这很有趣。当我的应用程序在后台运行时,我才会看到这个。此外,当我将我的应用程序带到前台时,在背景中构建的相关非对象消失!!!