2017-03-04 10 views
0

나는 UIViewController에 추가하는 UIView를 가지고 있으며 일반적으로 일을 올바르게하고 있는지 확인하기 위해 초기화 해제를 테스트하고 있습니다. 그러나 viewController 변수를 nil으로 설정하지 않고 .removeFromSuperView() 만 사용하면 UIView의 deinit() 메서드가 호출 될 때까지 UIView를 호출 할 때까지 호출되지 않습니다. 그러나 removeFromSuperView()를 사용하고 변수를 nil로 설정하면 deinit()가 바로 호출됩니다. 왜 그런가요?UIView가 다시 부모에 추가 될 때까지 deinit가 호출되지 않는 이유는 무엇입니까?

class TestView: UIView { 

    override init(frame: CGRect) { 
     super.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) 
     print("init is happneing") 
    } 

    deinit { 
     print("de init is happneing") 
    } 


    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 
} 

가 여기에 부모의 ViewController의 : 아무도 객체를 참조하지 않을 경우

class MyViewController: UIViewController { 
var tstview : TestView? 


    //adding the UIView by tapping on a button 
@IBAction func addView(_ sender: UIButton) { 

     let test = TestView() 
     tstview = test 
     tstview?.frame = CGRect(x: 50, y: 60, width: self.view.frame.width-100, height: self.view.frame.height-200) 
     tstview?.backgroundColor = UIColor.white 
     self.view.addSubview(tstview!) 
} 

    override func viewDidLoad() { 
     super.viewDidLoad() 
    } 

    //removing UIView by touching elsewhere 
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
     tstview?.removeFromSuperview() 
     // tstview = nil 

    } 


} 

답변

0

deinit가 호출

여기에 UIView() 클래스입니다. tstviewnil으로 설정하지 않으면 MyViewController가 여전히이를 참조하므로 deinit이 호출되지 않습니다. addView을 호출하면 tstview = test 문이 마침내 이전 뷰에 대한 마지막 참조를 제거하므로 디인ial라이저가 트리거됩니다.

Swift documentation에서 초기화 취소의 개념에 대해 자세히 읽을 수 있습니다.


당신이보기가 분리되는 즉시 통보 할 경우

, override willMove(toSuperview:) 대신.

class TestView: UIView { 
    ... 
    override func willMove(toSuperview newSuperview: UIView?) { 
     if newSuperview == nil { 
      print("removed from parent") 
     } 
    } 
} 
+0

답장을 보내 주셔서 감사합니다. 누출을 남기지 않으려 고합니다. 그 경우에는 willMove toSuperview가 도움이되지 않습니다. 나는 removeViewSuperview()가 왜 상위 뷰 컨트롤러에 UIView()의 다른 인스턴스를 추가 할 때까지 removeFromSuperview()가 비활성화되지 않는지 이해하려고 노력하고 있습니다. 그 이유는 그때만 deinit이 호출되기 때문입니다. 나는 문서를 보았지만 이유를 찾을 수 없다. – TheeBen

+0

@TheeBen 업데이트 된 첫 번째 단락을 확인하십시오. – kennytm

+0

니스! 이제 알겠다! 최대한 빨리 받아 들일거야. – TheeBen