2017-11-19 12 views
0

사용자 위치를 가져 오는 중, 필요할 때 사용자 위치를 가져 오기 위해 싱글 톤 클래스를 만들었습니다. 그러나 그것은 유지 사이클을 만들고 있습니다. LocationManager 클래스를 사용하면 deint가 호출되지 않습니다. 이 클래스를 사용하지 않으면 init이 예상대로 제대로 호출됩니다. WKInterfaceController에서 내 WKInterfacecontroller를 pop/self.dismiss 할 때 deinit이 호출되지 않는 이유

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 
    } 
} 
} 

, 나는

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) 
    }) 
} 

내가이 getUserCurrentLocation 방법을 WKInterface의 willActivate가 호출 될 때마다 호출이 메서드를 호출하고 있습니다. 다른 방법이 있습니까? 유지주기가 생성되지 않습니다.

답변

1

아무것도 LocationManager 클래스 자체가 잘못된 것 같다,하지만 당신은 onSuccessBlock 당신이 당신의 WKINterfaceController 클래스에서 호출하고있는 getUserCurrentLocation 기능에 전달 onFailedBlock에 강한 참조를 보유하고 있습니다. 해당 블록에 self을 보유하고있는 경우 LocationManagerWKInterfaceController 클래스에 대한 강력한 참조를 가지므로 deinit은 호출되지 않습니다. WKInterfaceController 코드를 넣을 수 있습니까? 그러면 더 말할 수 있습니다.

편집 : 네, selfonSuccessBlockweak으로 캡처하고 있지만, onFailedBlock을 강력하게 캡처하고 있습니다. onFailedBlock 시작 부분에 [weak self] in 문을 입력하면 작동합니다.

+0

그래서 변수를 약하게 만들거나 블록을 만드는 데 가장 좋은 방법은 무엇입니까? 약한. – user3350097

+0

'LocationManager' 클래스의 블록에 대한 강력한 참조를 보유해야합니다. 그렇지 않으면, 이들 블록은 다른 블록에 대한 강력한 참조가 없기 때문에 해제됩니다. 엄지 손가락의 규칙으로 당신은 항상 당신의 블록에서'약한 '자로'자기'를 잡아야한다. –

+0

나를 도우려는 사람 감사합니다 ... – user3350097