SNS앱을 만들고 있는 도중 Rx를 통해 테이블뷰에 데이터를 뿌려 주면서 발생하는 문제입니다.
사용자가 좋아요 버튼을 클릭하면, 해당 셀의 데이터가 업데이트되면서,
전체 테이블 뷰가 재로드되어 이미지 스크롤 뷰가 초기 위치로 리셋되는 문제가 발생했습니다.
초기 접근은
SNSDataModel
내의 좋아요 상태를 변경하는
뮤테이팅 함수를 구현하는 것이었습니다. 구조체는 값 타입이기 때문에
복사되는 성질을 이용했지만, 이는 같은 인스턴스를 참조하지 않고,
각각 별도로 동작하는 문제로 이어졌습니다.
(저가 틀린것일수도 있습니다…ㅠ)
mutating func changeLikeModel(_ userID: String, likeBool: Bool) {
if likeBool {
likes.append(userID)
} else {
if let index = likes.firstIndex(of: userID) {
likes.remove(at: index)
}
}
분신술을 쓴거 마냥 각자가 따로 놀게 되는 것을 미쳐 생각 하지 못했다.
Struct SNSDataArray: Equatable{
static func == (lhs: Self, rhs: Self) -> Bool {
}
var realPostData: [SNSDataModel] = []
func change(_ row: Int,_ model: SNSDataModel ){
realPostData[row] = model
}
}
다음 시도는
Equatable
프로토콜을 구현하여 데이터의 동등성을 비교하는 방식이었습니다.
이 방법도 구조적 한계로 인해 실패했습니다.시나리오는 이러하였는데
전체 모델수 가 같은면 같은거니
// 데이터 방출시 테이블 뷰
output.tableViewItems
.distinctUntilChanged() // 이부분에서 Equtable 의해 ㅎㅎ 반영안되겠징?
해당 코드에서 문제가 해결같은데?
라는 생각을 했었습니다… ㅠ
심지어 되고 있는줄 알았는데
하….. 나한테 왜그러는 거야 징짜
최종적으로 클래스를 사용하여 참조 타입의 특성을 활용하였습니다.
클래스 인스턴스는 메모리 주소가 고정되므로,
같은 인스턴스에 대한 변경이 가능했고,
Equatable
을 활용하여 UI 업데이트 시 불필요한 리로드를 방지할 수 있었습니다
model : 이 현재 쏘아진 클래스 이고
updatedPosts는 수정시 발생하는 주소인데 같은 주소임을 확인할 수가 있습니다.
static func == (lhs: SNSDataModel, rhs: SNSDataModel) -> Bool {
if lhs.postId == rhs.postId {
return true
}
return false
}
와 정말 이것을 고치기 위해서 하루를 꼬박 셌습니다.
정말 아직 기본기가 부족한 상태이구나 라는 생각을 다시한번 생각하게 되는 이슈였고
그냥 모른척 지나갈수도 있었겠지만 이것조차 못하는 자신이 너무 화가날것 같아 결국엔 원하는 대로
되게 되었습니다. 정말 후회없는 작업 결과물입니다....!