TableView 滞后太多,占用太多内存 Swift

Posted

技术标签:

【中文标题】TableView 滞后太多,占用太多内存 Swift【英文标题】:TableView lagging too much and taking up too much memory Swift 【发布时间】:2015-07-06 13:38:47 【问题描述】:

我有一个在 UIViewController 内使用 UITableView 的应用程序,每个单元格的形成方式是,有关问题或博客文章的信息在下载后存储在 CoreData 中。但是当我运行仪器工具时,我发现每次向下或向上滚动时都会获取该 CoreData。即使单元已经初始化,所以这与显然 NSDate 相结合也占用了内存的外观。当您向下滚动时,该程序占用了大约 40m 的内存和大约 60% 的 CPU!我一直在寻找如何只初始化一次但可以在任何地方找到它的答案。这是我的 TableView 代码:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCellWithIdentifier("tableviewcell", forIndexPath: indexPath) as! BlogTableViewCell

    let sortedPosts = SortPosts()
    let realresults = sortedPosts.sortData()




    if realresults.count > 0 
        println(cell)
        let date = realresults[indexPath.row].valueForKey("date") as? NSDate
        let numberOfTime = PostDateFormatter().getFormattedDate(date!)
        let content = realresults[indexPath.row].valueForKey("content") as! String
        let title = realresults[indexPath.row].valueForKey("title") as! String

        cell.configureCell(Post(title: title.html2String, author: realresults[indexPath.row].valueForKey("author") as! String, date: numberOfTime, content: content.html2String))
        tableView.hidden = false
        self.view.backgroundColor = UIColor(red: 255.0/255.0, green: 255.0/255.0, blue: 255.0/255.0, alpha: 255.0/255.0)
        myIndicator.stopAnimating()
        myIndicator.hidden = true
        
    else 
        if PostServices().isConnectedToNetwork() 
            println("Error 0 results returned......")
            self.tableView.reloadData()
        

    

    return cell

这里是 SortPosts:

class SortPosts 
func sortData() -> NSArray 
    var jsonin = NSArray()

    let formatter = NSDateFormatter()
    formatter.dateFormat = "Y-MM-dd\'T\'HH:mm:ss"

    var managedObjectContext : NSManagedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext!

    var request = NSFetchRequest(entityName: "Post")
    request.returnsObjectsAsFaults = false

    let sortDescriptor = NSSortDescriptor(key: "date", ascending: false)
    request.sortDescriptors = [sortDescriptor]

    var results : NSArray = managedObjectContext.executeFetchRequest(request, error: nil)!

    return results




这里是 PostDateFormatter:

class PostDateFormatter 
func getFormattedDate(date : NSDate) -> String 
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = NSDateFormatterStyle.ShortStyle
let dateInShortFormat = dateFormatter.stringFromDate(date)

let inter = date.timeIntervalSinceNow

var seconds = Int(abs(inter))
var minutes = seconds/60
var hours = minutes/60
var days = hours/24
var weeks = days/7


if seconds < 60 
return "\(seconds)s"
 else if minutes < 60 
return "\(minutes)m"
 else if hours < 24 
return "\(hours)h"
 else if days < 7 
return "\(days)d"
 else if weeks <= 8 
return "\(weeks)w"
 else if weeks > 8 
return "\(dateInShortFormat)"

    return "Something went wrong with date formatting"

【问题讨论】:

【参考方案1】:

您确实意识到,对于您正在调用的每个单元格;

   let sortedPosts = SortPosts()
   let realresults = sortedPosts.sortData() 

在 tableView 之外初始化所有数据会更有意义,或者肯定是在 cellForRowAtIndexPath 以外的某个时间点。

在别处构建项目的数组或字典,然后在 cellForRowAtIndexPath 中简单地引用数组中的项目。这样,您只需访问核心数据一次。

【讨论】:

最好是在viewDidLoad() 好吧,我在 viewDidLoad() 中做到了,内存已经达到 20m,大约 CPU 仍然很高,大约 60% 并且仍然滞后。这可能与 NSDate 有关吗? 您在设备上进行测试吗?忽略您在模拟器上运行时看到的所有内存/cpu 统计信息。 好吧,我在手机上测了一下,CPU在30%左右,内存在30meg左右。 我可以做些什么来让 NSDate 每次滚动时都不会被调用?【参考方案2】:

您在问题中所说的准确描述了 TableViews 的工作原理。每个单元格只有在屏幕上可见时才会出队。否则,内存中没有其他单元格,当显示新单元格时,它们必须出列,因此每次显示时都需要访问数据库和 CPU 以获取信息和绘图。

【讨论】:

我明白这一点,但有没有办法让 ram 不那么过度杀伤力。因为你现在几乎不能向下滚动,所以它会像疯了一样滞后。【参考方案3】:

如果您准备好迎接挑战,我建议您使用:asyncdisplaykit。

我相信它会帮助您解决记忆问题。 它最初是为了让 Facebook 的 Paper 成为可能。

http://asyncdisplaykit.org/

【讨论】:

以上是关于TableView 滞后太多,占用太多内存 Swift的主要内容,如果未能解决你的问题,请参考以下文章

buff/cache占用太多内存,如何释放内存?

Backstack上的Android Fragments占用太多内存

应用程序占用太多内存直到崩溃! (苹果手机)

Scikit-learn 随机森林占用太多内存

eclipse为啥占用太多cpu和内存?

Flutter 与 VS Code 和模拟器占用太多内存