如何释放GMSPlacePickerViewController占用内存,解决多次使用的异常问题?
这种情况我之前在项目里也碰到过,大概率是内存管理没做好或者SDK本身的一些小坑导致的,给你几个实际可行的解决思路:
务必正确销毁控制器实例,避免强引用泄漏
很多开发者容易忽略这一点:每次用完GMSPlacePickerViewController后,不仅要dismiss,还要把持有它的引用置为nil,不然控制器会一直留在内存里,累积多了就会触发内存警告,甚至影响网络请求的稳定性。
举个Swift的例子:// 初始化并展示Picker let config = GMSPlacePickerConfig(viewport: nil) self.placePicker = GMSPlacePickerViewController(config: config) self.placePicker?.delegate = self present(self.placePicker!, animated: true) // 在代理方法里处理完选择后清理 func placePicker(_ viewController: GMSPlacePickerViewController, didPick place: GMSPlace) { // 处理选中的地点逻辑 viewController.dismiss(animated: true) { // 这里一定要置空 self.placePicker = nil } } func placePickerDidCancel(_ viewController: GMSPlacePickerViewController) { viewController.dismiss(animated: true) { self.placePicker = nil } }如果你用的是Objective-C,记得在dismiss后把
_placePicker设为nil,打破强引用链。避免循环引用,尤其是闭包或代理场景
如果用了闭包回调(比如新版SDK的pickPlace方法),一定要用weak self防止循环引用,不然控制器永远无法被释放:let config = GMSPlacePickerConfig(viewport: nil) let placePicker = GMSPlacePickerViewController(config: config) placePicker.pickPlace { [weak self] place, error in guard let self = self else { return } if let place = place { // 处理地点 } self.dismiss(animated: true) // 这里不需要持有引用的话,直接让实例自动释放就行 } present(placePicker, animated: true)监听内存警告,主动清理闲置资源
可以在当前控制器里重写内存警告方法,当收到警告时,如果GMSPlacePickerViewController没有被展示,就主动销毁它:override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() if let picker = self.placePicker, !picker.isBeingPresented { picker.dismiss(animated: false) self.placePicker = nil } }升级Google Places SDK到最新版本
旧版本的SDK可能存在内存泄漏或者网络请求管理的bug,去Google的开发者文档确认最新版本,用CocoaPods或者Swift Package Manager更新后,很多这类问题会自动解决。考虑替代方案:用GMSAutocompleteViewController自定义选择流程
如果GMSPlacePickerViewController的问题始终无法解决,可以换成GMSAutocompleteViewController,它更轻量化,而且你能更精准地控制请求和内存。比如:let autocompleteController = GMSAutocompleteViewController() autocompleteController.delegate = self present(autocompleteController, animated: true) // 代理方法里处理 func viewController(_ viewController: GMSAutocompleteViewController, didAutocompleteWith place: GMSPlace) { // 处理地点 dismiss(animated: true) }这种方式每次用完dismiss后实例会自动释放,内存压力小很多,网络请求也更可控。
另外,"The network connection was lost."的提示,大概率是内存累积导致App的网络会话出现异常,当内存问题解决后,这个网络提示也会跟着消失。如果还是出现,可以在网络请求失败时,主动清理当前的Picker实例,重新创建一个新的再尝试。
内容的提问来源于stack exchange,提问作者ShashiKant_B

