LocationManager委托失效:locationManagerDidChangeAuthorization未触发ViewModel方法
你的委托机制失效主要有两个核心问题:
错误创建了新的ViewModel实例
在LocationManager的locationManagerDidChangeAuthorization方法中,你手动实例化了一个全新的LocationManagerViewModel,并尝试调用它的方法。但这个新实例和你实际业务中使用的LocationManagerViewModel完全无关,调用后就会被销毁,自然不会触发你期望的逻辑。未建立正确的委托关联
LocationManagerViewModel内部初始化了LocationManager,但从未将自身设置为该LocationManager的delegate。也就是说,LocationManager的delegate属性始终为nil,授权状态变化时根本找不到要通知的对象。
额外隐患:原代码存在循环引用风险——LocationManagerViewModel持有LocationManager,如果LocationManager强引用delegate(即ViewModel),两者会互相持有导致内存泄漏。
1. 修正LocationManager的委托调用逻辑
删掉locationManagerDidChangeAuthorization中手动创建ViewModel的代码,直接使用类本身的delegate属性:
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { print("Calling method locationManagerDidChangeAuthorization") // 移除这行错误代码:var delegate: LocationManagerDelegate? = LocationManagerViewModel() delegate?.locationManagerDelegateComunicationMethod() }
2. 建立ViewModel与LocationManager的委托关联
在LocationManagerViewModel的初始化方法中,将自身设置为locationManager的delegate:
class LocationManagerViewModel: ObservableObject, LocationManagerDelegate{ // some @Published properties here private var locationManager = LocationManager() init() { // 关键:将当前ViewModel设置为locationManager的代理 locationManager.delegate = self } func locationManagerDelegateComunicationMethod() { print("Received message from the LocationManager class!") // do something... } }
3. 修复循环引用问题
修改LocationManagerDelegate协议,添加AnyObject约束(限定仅类类型可遵守),并将LocationManager的delegate属性标记为weak:
// 添加AnyObject约束,让协议仅适用于类类型 protocol LocationManagerDelegate: AnyObject { func locationManagerDelegateComunicationMethod() } final class LocationManager: NSObject, CLLocationManagerDelegate { private let locationManager = CLLocationManager() // 使用weak修饰delegate,避免循环引用 weak var delegate: LocationManagerDelegate? // 其余代码保持不变... }
内容的提问来源于stack exchange,提问作者fs_tigre

