RxCocoa) UICollectionViewController를 바인딩 할 경우 앱이 죽는 버그

에러 내용 :

Assertion failed: This is a feature to warn you that there is already a delegate (or data source) set somewhere previously. The action you are trying to perform will clear that delegate (data source) and that means that some of your features that depend on that delegate (data source) being set will likely stop working.

If you are ok with this, try to set delegate (data source) to `nil` in front of this operation.

 

직역 하자면, 이미 delegate나 datasource가 이미 설정 되어서 내가 하는 작업을 수행 할 경우, 이미 설정된 delegate나 datasource에 의존하는 일부 기능이 정지 할 수도 있다는 뜻이다. 

 

기존코드

class ImageListCollectionViewController: UICollectionViewController {
    
    var viewModel: ImageListViewModel?

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.register(ImageListCollectionViewCell.self, forCellWithReuseIdentifier: ImageListCollectionViewCell.reuseIdentifier)
        viewModel?.fetching.drive(collectionView.rx.items(cellIdentifier: ImageListCollectionViewCell.reuseIdentifier, cellType: ImageListCollectionViewCell.self)) {  index, result, cell in
            URLSession.shared.dataTask(with: URLRequest(url: URL(string: result.imagePath)!)) { data, response, error in
                if error != nil {
                    print(error?.localizedDescription)
                } else {
                    DispatchQueue.main.async {
                        cell.picterestImageView.image = UIImage(data: data!)
                    }
                }
            }.resume()
        }
    }
    
}

ImageListCollectionViewController의 collectionView는 UICollectionViewController타입이므로 이미 내부적으로 datasource와 delegate를 ImageListCollectionViewController에게 할당 하고 있는 상태고, RxCocoa가 바인딩을 하려고 dataSource와 delegate를 자신에게 할당 하려고 할때, 이와 같은 오류가 뜨는것으로 보인다. 따라서 collectionView의 datasource와 delegate의 할당을 해제 해줘야 한다.

 

고친 코드

class ImageListCollectionViewController: UICollectionViewController {
    
    var viewModel: ImageListViewModel?

    override func viewDidLoad() {
        super.viewDidLoad()
        
        //datasource를 해제
        collectionView.dataSource = nil
        
        collectionView.register(ImageListCollectionViewCell.self, forCellWithReuseIdentifier: ImageListCollectionViewCell.reuseIdentifier)
        viewModel?.fetching.drive(collectionView.rx.items(cellIdentifier: ImageListCollectionViewCell.reuseIdentifier, cellType: ImageListCollectionViewCell.self)) {  index, result, cell in
            URLSession.shared.dataTask(with: URLRequest(url: URL(string: result.imagePath)!)) { data, response, error in
                if error != nil {
                    print(error?.localizedDescription)
                } else {
                    DispatchQueue.main.async {
                        cell.picterestImageView.image = UIImage(data: data!)
                    }
                }
            }.resume()
        }
    }
    
}