2016-12-13 4 views
1

메모리 누수의 원인이되는 뷰 컨트롤러 중 하나에서 강력한 참조에 문제가 있습니다. 먼저, 내 설정 :메모리 누수를 일으키는 강력한 참조가있는 컨트롤러보기

2 뷰 컨트롤러 (v1 및 v2). v1은 v2로, v2는 v1으로 다시 돌아 오는 닫기 버튼을 가지고 있습니다. v2에는 연결될 때까지 무한대로 다시 연결을 시도하는 코드가 들어 있습니다. (red5pro를 사용한 비디오 스트리밍). 여기에 코드입니다 :

func reconnect(){ 
     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(5.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) {() -> Void in 
      self.connectToStream() 
     } 
} 

연속 다시 연결 내 상황에서 바람직하다,하지만 사용자가 V2를 종료 할 때, 나는 다시 연결 중지 할. 하지만 현재 사용자가 v2를 떠난 경우에도 재 연결은 무한히 계속됩니다.

v2는 강력한 참조를 가지고 있으며 사용자가 종료 한 후에도 계속해서 살아 있기 때문에이 사실을 알게되었습니다. 따라서 reconnect() 메서드를 무한히 호출하는 코드가 계속 실행되고 있습니다. 온 다시 연결을 죽일 수있는 방법이 있나요

  1. : 나는 약한 참조로 모든 것을 변환 V2를 정리하려고거야,하지만 난 또한 몇 가지 대안을 고려하고, 나는 그것을 관한 몇 가지 질문을했다 viewDidDisappear 또는 뭔가, 그래서 내보기 컨트롤러 파괴되지 않습니다, 적어도 내 다시 연결 프로세스가 중지됩니까?

  2. v2에서 v1로 다시 나가면 사용자가 v2로 다시 들어가면 v2의 인스턴스를 새로 만들지 않고 동일한 인스턴스를 할당 할 수 있습니까?

+0

"매번 새로운 인스턴스를 생성하는 대신 v1의 동일한 인스턴스를 할당 할 수 있습니까?" ... 당신이 v1이 아니라 v2를 의미한다고 생각합니까? – Rob

+0

v1이 아니라 v2에 대해 정말로 생각하고 있다고 가정합니다. 일반적으로보기 컨트롤러를 팝하면 리소스를 해제하고 다시 표시해야 할 때 다시 만듭니다. 주변을 지킬 수있는 방법이 있지만, 조기 최적화 및/또는 심층적 인 설계 결함의 징조가 있습니다. View Controller는 자체 제작 비용이 상대적으로 저렴합니다. 네가 해산했다고해도 왜 그 일을 계속하도록 강요당하는 기분이 들까? – Rob

+0

@ yes 예, 내 잘못, 질문을 업데이트했습니다. – Prabhu

답변

3

dispatch_after 취소 할 수 없습니다 만, 몇 가지 옵션이 있습니다 :

  1. 사용 약한 참조, self을 해제 할 수 있습니다 :

    func reconnect() { 
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(5.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) { [weak self] in 
         self?.connectToStream() 
        } 
    } 
    

    을이 틀림 유지는 타이머가 진행되지만 뷰 컨트롤러를 유지하지 못하게하므로 뷰 컨트롤러가 해제되고 connectToStream은 호출되지 않습니다.

    weak var timer: NSTimer? 
    
    func reconnect() { 
        timer?.invalidate() 
        timer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: #selector(handleTimer(_:)), userInfo: nil, repeats: false) 
    } 
    
    func handleTimer(timer: NSTimer) { 
        self.connectToStream() 
    } 
    
    override func viewDidDisappear() { 
        super.viewDidDisappear() 
        timer?.invalidate() 
    } 
    

    참고이 selectorNSTimertarget에 강한 참조를 유지 기반하기 때문에 강한 참조주기가 있기 때문에, 당신은 (deinit에 취소 할 수 없습니다 : 뷰가 사라지면

  2. 사용 NSTimer 및 취소). 따라서이를 해결할 수있는 다른 적절한 이벤트를 찾아야합니다 (예 : viewDidDisappear).

+0

이 사진을 줄 것입니다. 뷰 컨트롤 참조주기 문제를 해결하지 않고도 내 문제를 해결할 수 있다면 뷰 컨트롤러가 멈추지 않고 그대로 둘 수 있습니까? 아니면 항상 뷰 컨트롤러에서 폐기하는 것이 목표입니까? – Prabhu

관련 문제