我使用MapKit
使用CLLocationManagerDelegate
来获取用户的位置。如果我要在ViewController的viewDidLoad()
功能中请求用户的位置,则会出现弹出窗口,询问用户输入的用户。注意:询问位置所需的两个属性(使用中的位置,以及始终和使用时的位置)已添加到Info.plist
即,
import UIKit
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate {
var locationManager: CLLocationManager?
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
self.locationManager?.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager?.requestWhenInUseAuthorization()
self.locationManager?.delegate = self
self.locationManager?.startUpdatingLocation()
}
}
上面的代码工作正常;当程序开始时,它会显示一个弹出窗口,询问用户的位置。
但是,如果我要创建一个新类MapController
并在该类中放入相同的代码,并在MapController
内创建viewDidLoad()
的新实例,则弹出窗口会立即消失程序运行时。
即,
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let mapController = MapController(viewController: self)
mapController.initialise()
}
}
import MapKit
class MapController: NSObject, CLLocationManagerDelegate {
private let viewController: UIViewController
private var locationManager: CLLocationManager
required init(viewController: UIViewController) {
self.viewController = viewController
locationManager = CLLocationManager()
}
func initialise() {
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.delegate = self
self.locationManager.startUpdatingLocation()
}
}
当上面的代码运行时,询问用户位置的弹出窗口会立即消失。
我的问题是:为什么当locationManager代码在viewDidLoad()中时弹出窗口保持不变,但是当代码被分成另一个类并调用到viewDidLoad()时,它会立即消失。为什么会这样?
如何将locationManager代码分离到另一个类中,而弹出窗口不会立即消失?
答案 0 :(得分:2)
这是一个内存管理问题。在ViewController
中,您在mapController
中创建名为viewDidLoad
的本地变量。在viewDidLoad
结束时,MapController
实例超出范围并被取消分配。
不是在viewDidLoad
中使用局部变量,而是创建属性。
class ViewController: UIViewController {
var mapController: MapController!
override func viewDidLoad() {
super.viewDidLoad()
mapController = MapController(viewController: self)
mapController.initialise()
}
}
但现在这会创建一个引用周期,因为MapController
保持对视图控制器的强引用。
因此,您还需要将viewController
的{{1}}属性更改为MapController
。