我試圖擺脫與 MKMapView 相關的記憶體泄漏。我認為主要問題是我創建整個專案時沒有使用故事板作為一系列視圖,我通過將 alpha 設定為 0 或將視圖縮小到零高度來管理這些視圖。我在 ViewController.swift 中初始化了一個 mapView,如下所示:
class ViewController: UIViewController{
//Properties
let mapView = MKMapView()
}
然后在另一個 .swift 檔案中添加 ViewController 的擴展名,例如:
extension ViewController {
private func setupMapViews(){
//MAPVIEW:
mapView.frame = CGRect(x: 0, y: view.frame.height, width: view.frame.width, height: 0)
mapView.overrideUserInterfaceStyle = .dark
mapView.mapType = .hybrid
mapView.delegate = self
}
在我的應用程式的主視圖上,我有一個按鈕,它使用影片連接到這個 mapView。在運行模擬器時檢查除錯導航器,我發現當 segue 發生時,記憶體使用量從 90 MB 躍升至 160 MB。當我按下已添加到 mapView 的完成按鈕時,記憶體使用量保持在 160 MB 左右,告訴我存在記憶體泄漏。起初,我嘗試在轉回主視圖控制器時簡單地將其從超級視圖中洗掉,但應用程式保持在 160 MB 左右,告訴我有一個保留周期。相反,我嘗試將 mapView 的宣告更改為弱變數,如下所示:
class ViewController: UIViewController{
//Properties
weak var mapView: MKMapView?
}
然后在 viewDidLoad() 中初始化它
override func viewDidLoad() {
super.viewDidLoad()
let mapV: MKMapView? = MKMapView()
self.mapView = mapV
}
但是現在當我嘗試從我的主視圖轉到 mapView 時,它沒有初始化,視圖也沒有出現。我究竟做錯了什么?
任何幫助表示贊賞,謝謝!
uj5u.com熱心網友回復:
你問:
如何正確分配/初始化弱變數?
你應該:
使用區域變數創建物件:
let mapView = MKMapView()在您的區域變數超出范圍之前(即,在當前方法中),將其添加到您的視圖層次結構中(以便您的視圖層次結構保持對它的強參考):
view.addSubview(mapView)更新您的屬性以維護
weak對這個新實體化MKMapView的 .self.mapView = mapView您可以稍后從視圖層次結構中洗掉地圖視圖:
mapView?.removeFromSuperview()當您這樣做時,地圖視圖將不再有任何強參考,并且該
weak屬性將自動設定為nil并且您的記憶體將被恢復。
因此,如果您想MKMapView在用戶點擊按鈕時添加您的,請將上述步驟移至您的按鈕處理程式(或此呼叫的方法)而不是viewDidLoad. 如果您在viewDidLoad沒有第 2 步的情況下保留此代碼,MKMapView則會立即解除分配。
幾點觀察:
在診斷記憶體消耗時,不要依賴第一次迭代的結果(這將包括快取期間使用的記憶體),而是關注后續迭代。
在一個快速測驗中,在 Xcode “Debug Navigator”中顯示的以 50mb 運行的應用程式中,當顯示地圖時,它會跳到 120mb,當關閉帶有地圖的視圖控制器時,它會下降到 85mb。然后,第二次向視圖控制器展示地圖時,它再次躍升到 120mb,并且解雇將其恢復到 85mb。它繼續使用這種模式,以便隨后使用地圖呈現和解除視圖控制器。因此,正在進行大量快取(價值約 35mb),但在后續啟動中缺乏持續的記憶體增長意味著沒有(實質性)泄漏。
分配工具(“產品”?“組態檔”?“分配”)更清楚地說明了這一點,在這里我展示并關閉了地圖視圖三次:

Let us assume that you did the above diagnostics and confirmed that you were losing memory for every iteration, not just experiencing cache behavior.
I would then run the app in the debugger, dismiss the map view within the app, and then use Xcode’s “Debug memory graph” feature to figure out what was keeping a strong reference. Here, I searched for
MKMapViewin the debug navigator, and it shows me the graph, with a white line going back to the view controller in question. (I ignore the lines in gray, as those show weak/unowned references.)
See

Now, I have signposts where I presented the view controller and dismissed it, but you can see that this was not relevant. When I removed all references to the map view (even before dismissing the view controller), memory is recovered correctly.
Bottom line, the problem does not rest in the code that you have shared with us thus far. You have something keeping a strong reference to the map view, and we will not be able to help you in the absence of a MCVE. But hopefully the above provides some diagnostic tools (especially the “Debug memory graph” feature).
The problem likely rests in either (a) how you're removing the map view from the view hierarchy; or (b) some strong reference cycle between the map view and its child objects (e.g. annotations, annotation views, etc.). But we do not have enough information to diagnose that.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/446949.html
