【问题标题】:Why deinit is not called when I pop/self.dismiss my WKInterfacecontroller为什么当我 pop/self.dismiss 我的 WKInterfacecontroller 时不调用 deinit
【发布时间】:2017-11-19 07:00:16
【问题描述】:

我正在获取用户位置,我创建了单例类来在需要时获取用户位置。但它正在创建保留周期。如果我使用 LocationManager 类,则不会调用 deint 。如果我不使用这个类这个de init 按预期正确调用。

class LocationManager: NSObject, CLLocationManagerDelegate  {
private var clLocationManager: CLLocationManager?
private var SuccessBlock:((_ latitude: String, _ longitude: String)->Void)?
private var OnFailedBlock:(()->Void)?
private var lat: String?
private var long: String?

static let shared: LocationManager = {
    let instance = LocationManager()
    return instance
}()

private override init() {
    super.init()
}


private  func invokeLocationManager() {

    if self.clLocationManager == nil {

        self.clLocationManager =  CLLocationManager()
        self.clLocationManager?.delegate = self
    }

    self.clLocationManager?.requestWhenInUseAuthorization()
    self.clLocationManager?.startUpdatingLocation()
}


func getUserCurrentLocation(onSucessBlok onSucessBlock:@escaping (_ lat: String, _ long: String)->Void, onFailedBlok onFailedBlock:@escaping ()->Void) ->Void {

    self.SuccessBlock = onSucessBlock
    self.OnFailedBlock = onFailedBlock
    self.invokeLocationManager()
}



func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

    self.clLocationManager?.stopUpdatingLocation()
    if locations.count > 0 {

        let userLocation = locations[0]
         self.long = String(userLocation.coordinate.longitude);
         self.lat = String(userLocation.coordinate.latitude);

        if self.SuccessBlock != nil {

            self.SuccessBlock!(self.lat!, self.long!)
            self.SuccessBlock = nil
        }

    } else {

        if self.OnFailedBlock != nil {

            self.OnFailedBlock!()
            self.OnFailedBlock = nil
        }
    }
}

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {

    if self.OnFailedBlock != nil {

        self.OnFailedBlock!()
        self.OnFailedBlock = nil
    }
}
}

从WKInterfaceController,我调用这个方法

override func willActivate() {
    super.willActivate()
   self.getUserLocation()
}

private func getUserLocation() {

    LocationManager.shared.getUserCurrentLocation(onSucessBlok: { [weak self] (lat, long) in

        if CommonHelper.isStringValid(string: lat) && CommonHelper.isStringValid(string: long) {

            self?.fillInfoToDictionary(value:lat, key: KLatitude, type: InfoType.Acceleration)
            self?.fillInfoToDictionary(value:long, key: KLongitude, type: InfoType.Acceleration)

        }

    }, onFailedBlok: {


        self.fillInfoToDictionary(value:"0", key: KLatitude, type: InfoType.Acceleration)
        self.fillInfoToDictionary(value:"0", key: KLongitude, type: InfoType.Acceleration)
    })
}

每次调用 WKInterface 的 willActivate 时,我都会调用这个 getUserCurrentLocation 方法。 还有其他更好的方法吗?这样就不会创建保留周期。

【问题讨论】:

    标签: ios swift watchkit


    【解决方案1】:

    LocationManager 类本身似乎没有任何问题,但您持有对 onSuccessBlock 和 onFailedBlock 的强引用,该引用在您从 @987654325 调用的 getUserCurrentLocation 函数中传递@ 班级。如果您在这些块中保留self,则LocationManager 将对您的WKInterfaceController 类具有强引用,因此不会调用deinit。你能把你的WKInterfaceController的代码放上去吗?那么我们可以说更多。

    编辑:是的,您在onSuccessBlock 中将self 捕获为weak,但在onFailedBlock 中则非常强烈。如果您将[weak self] in 语句放在onFailedBlock 的开头,它应该可以工作。

    【讨论】:

    • 那么使块变量变弱的最佳方法是什么,或者这是使块变弱的必要条件。弱。
    • 你必须对 LocationManager 类中的块进行强引用,因为如果你不这样做,这些块将被释放,因为没有其他东西对它们拥有强引用。根据经验,您应该始终在您的块中将self 捕获为weak。
    猜你喜欢
    • 2014-07-24
    • 2021-05-16
    • 2017-03-17
    • 2023-03-20
    • 2020-08-11
    • 1970-01-01
    • 2019-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多