2016-10-27 4 views
0

일부 할당 해제 문제 및 아마도 알아 내지 못하는 강력한 또는 순환 참조를 처리하고 있습니다. 나는 3 개 UIView들 아래와 같이 인스턴스화 한 :강력한 참조 및 UIView 메모리 문제

나는 스토리 보드에서 내부 UIView을 추가 한 하나의 주 ViewController가와 UIView 같은 클래스 안에 weak 콘센트가 있습니다

class ViewController : UIViewController { 

    //MARK: - outlets 
    @IBOutlet weak var firstView: FirstUiview! 

} 

두 번째 UIView 인을 첫 번째 관점에 하위 뷰로서 첨가 프로그래밍 같은

class FirstUiview : UIView { 

     //creating an instance of secondUiView 
     lazy var mySecondView: SecondViewClass = { 
      let dv = SecondViewClass() 
      dv.backgroundColor = UIColor.red 
      return dv 
     }() 


     //sometime later by clicking on a button 
     self.addSubview(mySecondView) 

     //a button will be tapped to remove mySecondView; 
     //later will be called at some point upon tapping: 

     func removingSecondViewByTapping() { 
     if mySecondView.isDescendant(of: self) { 
      mySecondView.removeFromSuperview() 
     } 
     } 

} 

이제 SecondViewClass은 다음과 같습니다

사용자가 mySecondView를 제거한 다음 내가 mySecondView의 모든 서브 뷰가 해제 사라 것으로 예상 (같은 ViewController 여전히) 다른 시간에 다시 추가 있지만, 버튼을 탭하면 이제
class SecondViewClass : UIView { 

     //in this class I create bunch of uiview objects like below: 
     lazy var aView : UIView = { 
     let hl = UIView() 
     hl.tag = 0 
     hl.backgroundColor = UIColor.lightGray 
     return hl 
     }() 

     self.addSubview(aView) //... this goes on and I add other similar views the same way. 

     //creating an instance of thirdView 
     var let thirdView = UIView() 
     self.addSubview(thirdView) 

} 

모두 거기에있다. 나는 누군가가 나에게 그것을 지적 할 수 있다면 나는 많은 것을 감사 할 것이다. 나는 강한 참고를 유지하고 있는가? 아니면 순환 참조 문제가 있는가? 아니면 다른 뭔가?

+0

왜 당신이 2 뷰의 하위 뷰를 기대 : 사용자 정의 속성은 뷰 계층 구조에서 제거 weak을이기 때문에, 당신의 weak 참조가 자동으로 nil이 될 것이다 (따라서 유일한 강한 참조를 제거) 없어 졌니? Superview에서'mySecondView'를 제거한다고해서 모든 서브 뷰가 제거되지는 않습니다. – dan

+0

@dan 오 잠깐, 나는 view.removeFromSuperview가 공개하고 그 서브 뷰를 포함하여 뷰를 파괴 할 것이라고 생각했는데, 서브 뷰가 보유한 것에 대한 참조가 없다면 그렇지 않습니까? 그렇지 않다면 하위 뷰를 포함하여 보내는보기를 완전히 제거 할 수있는 방법을 안내 할 수 없습니까? – TheeBen

답변

4

addSubview을 호출 할 때보기, 사용자 지정 속성 및보기 계층 구조 참조에 대한 두 가지 강력한 참조가 있습니다. 뷰 계층 구조에서 뷰를 제거하면 클래스 자체가 여전히 강력한 참조를 갖습니다.

참조를 선택적으로 설정하여이 문제를 해결할 수 있으며 removeFromSuperview으로 전화 할 때 수동으로 참조 번호를 nil으로 설정할 수도 있습니다. 또는 weak 참조를 사용하여 뷰 계층 구조가 강력한 참조를 유지하도록하여이 문제를 해결할 수도 있습니다.

class FirstView: UIView { 

    weak var secondView: SecondView?  // note the `weak` reference, which is obviously an optional 

    //sometime later by clicking on a button 

    func doSomething() { 
     let subview = SecondView() 
     subview.backgroundColor = .red 
     self.addSubview(subview) 
     secondView = subview 
    } 

    // a button will be tapped to remove secondView; 
    // later will be called at some point upon tapping ... 

    func removingSecondViewByTapping() { 
     secondView?.removeFromSuperview() 
    } 
} 
+0

답장을 보내 주셔서 감사합니다. 올바른 설명과 대답처럼 보입니다. 나는 여기에서 그것을 단순화하려고 노력 했으므로이 문제가 저보다 더 깊을 까봐 두렵습니다. 매우 명확한 대답! 나는 아직 잠금 장치없이 이것을 시도했다. 내 세 번째보기에는 부모보기가 준수하는 프로토콜이 있습니다. 다른 문제 일 수 있습니까? 약한 프로토콜 대리인, 즉 http://stackoverflow.com/a/24104371/5601401과 같은 것임을 확인했습니다. – TheeBen

+0

예, 약한 프로토콜을 사용하지 못하는 것도 문제가 될 수 있습니다. 따라서 위의 내용을 수정하고 '약한'대리자 참조를 사용하도록 설정 했는데도 여전히 할당 취소 된보기가 표시되지 않으면 강력한 참조를 유지하고있는 것을 진단해야합니다. "Debug Memory Graph"(http://stackoverflow.com/a/30993476/1271826 참조)를 사용하면 추가로 발생하는 문제를 추적하는 데 유용 할 수 있습니다. – Rob