>source

클래스에 UICollectionView가 다음과 같이 선언되어 있습니다. @IBOutlet 약한 var artworkCollectionView : UICollectionView!

이 클래스에는 두 개의 다른 View Controller에 의해 호출되는 하나의 델리게이트 메소드가 있습니다.이 VC 중 하나는 팝업이고 다른 하나는 일반 VC입니다.

델리게이트 메소드는 데이터베이스에서 일부 데이터를 가져온 다음 클로저 내에서 호출하는 컬렉션 뷰를 업데이트합니다. self.artworkCollectionView.reloadData ()

팝업 VC가 delegate 메소드를 호출하면 모든 것이 잘 작동합니다. 그러나 self.artworkCollectionView.reloadData ()에 도달 할 때 일반 VC에 의해 대리자 메서드가 호출되면 악명 높은 치명적 오류가 발생합니다. 임시적으로 선택적 값을 래핑하지 않고 nil을 발견했습니다.

셀 reuseIdentifier에 대한 모든 참조를 확인했으며 모두 정확합니다. UICollectionView가 weak var로 선언되었으므로 현재 클래스에서 팝업으로 이동 한 다음 팝업에서 대리자 메서드를 호출하면 참조가 손실되지 않지만 현재 클래스에서 정상으로 갈 때 VC 다음 일반 VC는 델리게이트 메서드를 호출하여 약한 var에 대한 참조가 손실되므로 nil로 "표시"됩니다.

@IBOutlet weak var artworkCollectionView: UICollectionView!
override func viewDidLoad() {
    super.viewDidLoad()
    // Set up
    artworkCollectionView.dataSource = self
    artworkCollectionView.delegate = self
    artworkCollectionView.isUserInteractionEnabled = true
    artworkCollectionView.allowsSelection = true
    artworkCollectionView.register(UINib(nibName: 
    "MyCollectionViewCell", bundle: nil), 
    forCellWithReuseIdentifier: "cell")
}

// delegate method
func reloadCollections() {
    retrieveAlbumRatings { (isAlbum) in
        if isAlbum {
            self.retrieveAlbumData(completion: { (isFinished) in
                if isFinished {
                    // Reload collection views
                    self.artworkCollectionView.reloadData()
                }
            })
        }
    }
}

내가 옳다면 내 질문은 : var varCollectionCollectionView를 약하게 줄 수있는 방법 : UICollectionView! 현재 클래스에서 일반 VC 로의 흐름에서 손실되지 않도록 강한 참조?

수정 : 여기까지 내가 시도한 것이 있습니다 :

  1. 콘센트 선언에서"약"을 제거하여 다음과 같이 만듭니다 : @IBOutlet var artworkCollectionView : UICollectionView! 하지만 같은 오류가 발생했습니다

  2. 오버라이드 performSegue를 통해 artworkCollectionView를 일반 VC에 전달한 다음 대리자 메서드의 인수로 다시 전달했습니다. 이로 인해 치명적인 오류는 발생하지 않지만 UICollectionView 콘센트에 대한 약한 참조가 손실되었다고 생각하기 때문에 UICollectionView를 다시로드하지 않습니다.

도움을 주셔서 감사합니다 (면책 조항 : Swift를 처음 접합니다.)

  • 답변 # 1

    와이즈 비즈

      흐름은 위의 코드가 포함 된 VC가있는 것으로 보이며, VC는 팝업을 열거 나 "일반 VC"에 대한 표준 푸시 세그 (sight segue)를 수행 할 수 있습니다.

      팝업 VC 또는 일반 VC에서 일부 작업을 수행하고 일부 데이터를로드 한 다음 사용자가 원래 VC (

      Inside this class there is one delegate method called by two other View Controllers, one of these VC is a pop up, the other one is a normal VC.

      The delegate method gets some data from the database and then updates the collection view calling inside a closure: self.artworkCollectionView.reloadData()

      )로 돌아갈 때  해당 데이터로 업데이트됩니다.

      문제는 다음과 같습니다.

      와이즈 비즈

      여러분은 우려를 분리하고 싶습니다. VC간에 이상한 의존성을 피하기 위해 VC간에 전달하려는 내용에 대해 신중하게 생각해야합니다. 여러 가지 이유로 콘센트를 전달하지 않을 것입니다. 먼저 콘센트를 변경하기로 결정한 경우 여러 VC에서 콘센트를 추적해야합니다. 두 번째는 콘센트의 상태를 추적하기 위해 너무 많은 정신 체조가 필요하다는 것입니다. 콘센트는 수명주기의 특정 단계에서만 설정되도록 보장됩니다. 예를 들어 UICollectionView 의 segue에서 대상 VC를 검색하는 경우  그 당시 콘센트를 참조하려고하면 아직 설정되지 않았기 때문에 모두 0이됩니다.

      위 코드를 포함하는 VC가

      I passed artworkCollectionView to the normal VC via override performSegue and then passed it back as an argument of the delegate method. This does not give me the fatal error but also it does not reload the UICollectionView because I think that anyway the weak reference to the UICollectionView outlet is lost. You shouldn't be passing anything around like this in most cases unless you have a really good reason to do so (I don't see one).

      에 표시되는 내용을 제어하는 ​​유일한 이유 여야하는 이유는 다음과 같습니다.  그리고 언제. 여기서 문제는 팝업 또는 일반 VC가 대리자 메서드를 호출하거나 하나의 VC에서 다른 VC로 콘센트를 전달하는 것과 같은 이상한 일을하는 대신 데이터를 전달하는 것이 아니라 접근하는 방법입니다.

      가장 간단한 예는 다음과 같습니다.

        팝업 VC와 일반 VC는 실제로 코드를 가져 오기 위해 코드를 호출합니다. 데이터.

        그러면 팝업 VC를 실제로 어떻게 설정했는지에 따라 원래 VC의 일반 VC, prepareForSegue:sender: 사용  또는 와이즈 비즈  원본 VC에 대한 참조를 가져옵니다.

        해당 참조를 통해 데이터를 원본 VC로 설정하십시오.

        필요한 경우 팝업 VC 또는 일반 VC를 해제합니다 (특정 앱에 따라 사용자가 artworkCollectionView 를 푸시하도록 할 수 있음)  대신 사용하지 않음).

        원래의 VC가 다시 표시되면 수명주기 메소드에 코드를 추가하십시오. 와이즈 비즈  데이터의 내용을 와이즈 비즈  그 당시에.

        원래의 VC 외부로 콘센트를 전달해야하는 이유는 없습니다.

  • 답변 # 2

    짧은 대답 : 그렇게하지 마십시오. 뷰 컨트롤러의 뷰를 개인용으로 취급해야합니다. 다른 객체가 컬렉션 뷰를 다시로드하도록 호출하도록 메소드를 뷰 컨트롤러에 추가해야합니다.

    더 긴 대답은 뷰 컨트롤러가 화면에있는 한 뷰 컨트롤러의 컬렉션 뷰가 달라 붙어야한다는 것입니다. 객체 수명주기와 ARC 작동 방식에 대해 잘 이해하지 못하는 것 같습니다. 그 내용을 잘 읽고 이해하기 전까지 연습을하세요.

    다음과 같이 해보십시오 :

    parentViewController
    
    

    ...

    presentingViewController
    
    

    UIButton

  • 이전 system - 하드웨어 프리 페 처가 비활성화되어 있는지 확인하는 방법
  • 다음 reactjs - 반응 js에서 몇 개월과 몇 년 사이에 들어가는 방법?