简体   繁体   English

UITableView 滚动性能问题

[英]UITableView scrolling performance problem

I am currently working as a 5 month junior ios developer.我目前是一名 5 个月的初级 ios 开发人员。

The project I'm working on is an application that shows the prices of 70 cryptocurrencies realtime with websocket connection.我正在进行的项目是一个应用程序,它通过 websocket 连接实时显示 70 种加密货币的价格。

we used websocket connection, UItableview, UITableViewDiffableDataSource, NSDiffableDataSourceSnapshot while developing the application.我们在开发应用程序时使用了 websocket 连接、UItableview、UITableViewDiffableDataSource、NSDiffableDataSourceSnapshot。

But right now there are problems such as slowdown scrolling or not stop scroling and UI locking while scrolling in the tableview because too much data is processed at the same time.但是现在在tableview中滚动时会出现滚动速度变慢或不停止滚动和UI锁定等问题,因为同时处理的数据太多。

after i check cpu performance with timer profiler I came to the conclusion that updateDataSource and updateUI functions exhausting the main thread.在我使用计时器分析器检查 CPU 性能后,我得出的结论是 updateDataSource 和 updateUI 函数耗尽了主线程。

func updateDataSource(model: [PairModel]) {
    var snapshot = DiffableDataSourceSnapshot()
    let diff = model.difference(from: snapshot.itemIdentifiers)
    let currentIdentifiers = snapshot.itemIdentifiers
    
    guard let newIdentifiers = currentIdentifiers.applying(diff) else {
            return
        }
    snapshot.appendSections([.first])
    snapshot.deleteItems(currentIdentifiers)
    snapshot.appendItems(newIdentifiers)
    
    dataSource?.apply(snapshot, animatingDifferences: false, completion: nil)
}

func updateUI(data: SocketData) {
    
    guard let newData = data.data else { return }
    guard let current = data.data?.price else { return }
    guard let closed = data.data?.lastDayClosePrice else { return }
    
    let dailyChange = ((current - closed)/closed)*100
    
    DispatchQueue.main.async { [self] in
        
        if model.filter({ $0.symbol == newData.pairSymbol }).first != nil {
            let index = model.enumerated().first(where: { $0.element.symbol == newData.pairSymbol})
            guard let location = index?.offset else { return }
            model[location].price = current
            model[location].dailyPercent = dailyChange
            
            if calculateLastSignalTime(alertDate: model[location].alertDate) > 0 {
                //Do Nothing
            } else {
                model[location].alertDate = ""
                model[location].alertType = ""
            }
            
            if let text = allSymbolsView.searchTextField.text {
                if text != "" {
                    filteredModel = model.filter({ $0.name.contains(text) || $0.symbol.contains(text) })
                    updateDataSource(model: filteredModel)
                } else {
                    filteredModel = model
                    updateDataSource(model: filteredModel)
                }
            }
        }
        delegate?.pricesChange(data: self.model)
    }
}

Regards.问候。

ALL of your code is running on the main thread.您的所有代码都在主线程上运行。 You have to wrap your entire updateUI function inside a DispatchQueue.global(qos:) , and then wrap your dataSource.apply(snapshot) line inside a DispatchQueue.main.async .您必须将整个updateUI function 包装在DispatchQueue.global(qos:)中,然后将dataSource.apply(snapshot)线包装在DispatchQueue.main.async中。 the dataSource.apply(snapshot) line is the only UI work you're doing in all that code you posted. dataSource.apply(snapshot)行是您在发布的所有代码中所做的唯一 UI 工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM