从核心数据到表的数据加载非常缓慢

Posted

技术标签:

【中文标题】从核心数据到表的数据加载非常缓慢【英文标题】:Data loading from core data to table very slowly 【发布时间】:2015-06-25 05:18:50 【问题描述】:

我在核心数据中有 100 行的表,在 tableView 中我加载过滤的 25 行。当我在应用程序中打开这个 UIViewController 需要将近 2 秒,我认为它非常慢。我在 iPhone 5 上测试我的应用程序。可能是我做错了什么吗? 我看到所有行的 cellForRowAtIndexPath 方法调用了 4 次:1-25,然后再调用 1-25 等。可以吗? 当我只加载 1 行时,它运行得很快。

class TipsViewController: UIViewController, UITableViewDelegate


    @IBOutlet weak var tableView: UITableView!
    var tips = [Tips]()

    lazy var managedObjectContext : NSManagedObjectContext? =
    
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        if let managedObjectContext = appDelegate.managedObjectContext
        
            return managedObjectContext
        
        else 
            return nil
        
    ()

    let defaults = NSUserDefaults.standardUserDefaults()
    var languge:String!

    override func viewDidLoad()
    
        super.viewDidLoad()
        languge = defaults.objectForKey("language") as! String
        fetchLog()
    

    func fetchLog()
    
        let fetchRequest = NSFetchRequest(entityName: "Tips")
        let sortDescriptor = NSSortDescriptor(key: "id", ascending: true)
        fetchRequest.sortDescriptors = [sortDescriptor]
        fetchRequest.predicate=NSPredicate(format: "language=%@", languge)
        if let fetchResults = managedObjectContext!.executeFetchRequest(fetchRequest, error: nil) as? [Tips]
        
            tips = fetchResults
        
    

    func numberOfSectionsInTableView(tableView: UITableView) -> Int
    
        return 1
    

    func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int
    
        return tips.count
    

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> TipsTableViewCell
    
        let cell = tableView.dequeueReusableCellWithIdentifier("cellt", forIndexPath: indexPath) as! TipsTableViewCell
        cell.tipsTextView?.text = tips[indexPath.row].textShort
        cell.tipsTextView.editable=false
        cell.tipsTextView.userInteractionEnabled=false
        cell.tipsTextView.textColor = UIColor(red: 0x7E/255, green: 0x7A/255, blue: 0x7F/255, alpha: 1.0)
        cell.selectionStyle = UITableViewCellSelectionStyle.Default
        return cell
    

    func tableView(_tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
    
        let cell = tableView(_tableView, cellForRowAtIndexPath: indexPath)
        return cell.getHeight()
    

    override  func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!)
    
        if(segue.identifier == "showDetailx")
            var indexPath:NSIndexPath = self.tableView.indexPathForSelectedRow()!
            var detailViewController:TipViewController = segue.destinationViewController as! TipViewController
            detailViewController.tip = tips[indexPath.row]
        
    

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
    
        self.performSegueWithIdentifier("showDetailx", sender: self)
    

    func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,
        forRowAtIndexPath indexPath: NSIndexPath)
    
        if cell.respondsToSelector("setSeparatorInset:")
        
            cell.separatorInset = UIEdgeInsetsZero
        
        if cell.respondsToSelector("setPreservesSuperviewLayoutMargins:")
        
            cell.preservesSuperviewLayoutMargins = false
        
        if cell.respondsToSelector("setLayoutMargins:")
        
            cell.layoutMargins = UIEdgeInsetsZero
        
    

【问题讨论】:

如果您不需要为单元格设置不同的高度,请删除 estimatedHeightForRowAtIndexPath 函数。这会影响性能。如果所有单元格的高度相同,则可以使用 tableview 属性设置单元格高度。并通过评论函数 willDisplayCell 来检查性能。 【参考方案1】:

您在估计的HeightForRowAtIndexPath 上有一个问题。您在那里调用 cellForRowAtIndexPath,这就是您再次调用此方法的原因。您可以删除该代码并执行以下操作:

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat

    return self.heightForBasicCellAtIndexPath(indexPath)


func heightForBasicCellAtIndexPath( indexPath: NSIndexPath) -> CGFloat

    var sizingCell: UITableViewCell? = nil;
    var token: dispatch_once_t = 0
    dispatch_once(&token) 
        sizingCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as? TipsTableViewCell
    
    return sizingCell!.frame.size.height;

此方法使用 GCD 实例化一个 sizingCell 以确保它只创建一次。

希望对你有帮助

【讨论】:

感谢您的回答!我在初始化之前收到错误变量“sizingCell”被闭包捕获 hm,如果你把 'let' 改成 'var' 会解决你的问题吗?我是从头开始写的,所以我通过 xcode 检查它并编辑我的答案 我编译了该代码,它可以正常工作。您还有性能问题吗? 现在 cellForRowAtIndexPath 调用了一次,但是 heightForBasicCellAtIndexPath 调用了五次。它看起来很钢 这很正常,因为 heightForRow 会调用 uitableview 中的每个单元格。快速查看本教程raywenderlich.com/87975/… 另外,如果您有固定的单元格大小,也许最好硬编码高度常数【参考方案2】:

我删除 heightForRowAtIndexPath 和estimatedHeightForRowAtIndexPath 并添加到 viewDidLoad() 这个:

tableView.rowHeight = UITableViewAutomaticDimension
 tableView.estimatedRowHeight = 160.0

【讨论】:

以上是关于从核心数据到表的数据加载非常缓慢的主要内容,如果未能解决你的问题,请参考以下文章

iphone中Json数据加载缓慢

PyTorch:加速数据加载

在 XAMPP 服务器上运行的网页加载非常缓慢

Kendo UI Dropdownlist 从大型数据源加载缓慢

将数据插入 Oracle 表的最快方法是啥?

无法在表格视图中加载核心数据?