iosswiftuitableviewrx-swiftrx-cocoa

Memory Issue Possibly Related RxCocoa Binding Method


I have this binding method of RxCocoa:

   func bindTableView() {
        data.asObservable()
            .bind(to: tableView
                    .rx
                    .items(cellIdentifier: dealCellID, cellType: DealTabCell.self)
            )
        {
            row, profileData, cell in
            cell.configureProfile(dataModel: profileData)
        }
        .disposed(by: disposeBag)
    }

Data comes from Firebase but it loads at once and as I scroll down memory use goes up to over 1.7 GB. I thought reusable cells automatically take care of the memory because if you are not seeing a cell it doesn't use memory.

Firebase closure:

db.collectionGroup("deals").whereField("Sender", isEqualTo: senderEmail!).addSnapshotListener { (snapshot, error) in
            guard error == nil else {
                print("error?.localizedDescription collectiongroup = \(error?.localizedDescription)")
                return
            }
            self.dealNumber = snapshot?.documents.count ?? 0
            DispatchQueue.main.async {
                self.dealsPosted.attributedText = NSMutableAttributedString()
                    .bold("\(self.dealNumber)\n")
                    .normal("Deals")
            }
            for document in snapshot!.documents {
                let data = document.data()
                if let sender = data["Sender"] as? String,
                   let image = data["ImagePath"] as? String,
                   let dealTitle = data["DealTitle"] as? String,
                   let dealDesc = data["DealDesc"] as? String,
                   let storeID = data["StoreID"] as? String,
                   let storeTitle = data["StoreTitle"] as? String,
                   let dealID = data["DealID"] as? String,
                   let userName = data["UserName"] as? String,
                   let distance = data["Distance"] as? Double,
                   let senderUID = data["SenderUID"] as? String {
                    
                    self.getImageFromURLfromFirebase(path: image, dealTitle: dealTitle, dealDesc: dealDesc, storeTitle: storeTitle, storeID: storeID, dealID: dealID, sender: sender, userName: userName, distance: distance, senderUID: senderUID)
                }

In that getImageFromURLfromFirebase method I just download image from url and behavior relay accepts another value. I can provide additional code. That means in the loop of that firebase method every time something like this works:

DispatchQueue.main.async {
                    userDealsRelay.accept(userDeals.removingDuplicates())
                }

That object is this:

let userDealsRelay : BehaviorRelay<[DealModel]> = BehaviorRelay(value: [])

I am sure the memory usage is caused by tableview because it only happens when I scroll down.
By the way it stops when I am at the bottom and go up again. it is not infinitely growing.

struct DealModel: Hashable {
    var storeID: String?
    var dealImage: UIImage?
    var dealTitle: String?
    var dealDesc: String?
    var dealID : String?
    var storeTitle: String?
    var sender: String?
    var userName: String?
    var distance: Double?
    var senderUID: String?
    
    init(storeID: String?, dealImage: UIImage?, dealTitle: String?, dealDesc: String?, dealID: String?, storeTitle: String?, sender: String?, userName: String?, distance: Double?, senderUID: String?) {
        self.storeID = storeID
        self.dealImage = dealImage
        self.dealDesc = dealDesc
        self.dealTitle = dealTitle
        self.dealID = dealID
        self.storeTitle = storeTitle
        self.sender = sender
        self.userName = userName
        self.distance = distance
        self.senderUID = senderUID
    }
}

and

let profileData: DealModel

Solution

  • This has nothing to do with RxCocoa's binding method.

    Your DataModel holds a UIImage. You are downloading the image for each cell and the caching the image in the DataModel. Therefore, your memory should increase as more cells are displayed. This would happen even if you weren't using Rx.