首页 文章

在Swift 3中出现可重复使用的单元格非常慢

提问于
浏览
0

出列一个单元格需要0.5-1.0秒,这意味着我的UITableView需要超过2-3整秒才能加载,即使它只有4行 .

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var cellid = "NumberCell"
    var isnumber = true
    if indexPath.row == 0 {
        cellid = "TextCell"
        isnumber = false
    }

    NSLog("before dequeue \(indexPath)")
    let cell = tableView.dequeueReusableCell(withIdentifier: cellid, for: indexPath) as! TextfieldTableViewCell
    NSLog("dequeued")

    // ...

    return cell
}

直接在之前和之后的NSLog()语句显示出队从 07.4708.38 .

2017-07-25 22:07:07.471898-0700 myapp [10209:4507471]出列前[0,0] 2017-07-25 22:07:07.679715-0700 myapp [10209:4507471] [MC]系统组容器for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles 2017-07-25 22:07:07.683843-0700 myapp [10209:4507471] [MC]阅读从公共有效的用户设置 . 2017-07-25 22:07:08.386960-0700 myapp [10209:4507471]出局

细胞非常简单 . 它只有一个UILabel和一个UITextField,UITextField有一个Editing Changed动作 . 而已 .

enter image description here

什么可能导致它花费很长时间才能使一个细胞出列?是关于System组容器的其他两个系统NSLog()吗?

它使我的应用程序几乎无法使用,因为当我尝试切换到此视图控制器时,应用程序似乎在设置4行时锁定2-4秒 .

我在Objective-C中制作了数百个UITableViewControllers,我从未遇到过这个问题 . 我错过了Swift 3的奇怪之处吗?

3 回答

  • 0

    2017-07-25 22:07:07.679715-0700 myapp [10209:4507471] [MC] systemgroup.com.apple.configurationprofiles路径的系统组容器是/private/var/containers/Shared/SystemGroup/systemgroup.com . apple.configurationprofiles 2017-07-25 22:07:07.683843-0700 myapp [10209:4507471] [MC]从公共有效用户设置中读取 .

    ⚠️这是 OS Level 的日志 . 哪个延迟出列你的 UITableCell

    您可以在 xcode 中禁用不需要的日志 . 如下

    1-从Xcode菜单打开: Product > Scheme > Edit Scheme

    2-在您的环境中变量在值集 disable 中设置 OS_ACTIVITY_MODE

    enter image description here

    只有在调试应用程序时才会遇到此问题 . 这将在真实设备上正常运行 .

  • 1

    我终于找到了问题,这完全是我的错 . 我不小心在每个领域请求第一响应者 .

    为了方便起见,我已经覆盖 setSelected(_:animated:) ,这样如果我触摸了行的文本字段将成为第一响应者的行(以防万一我试图点击一个字段而错过了) . 问题是我忘了在 becomeFirstResponder() 电话周围加上一个if语句 .

    不好的代码:

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    
        self.textfield.becomeFirstResponder()
    }
    

    在将单元格出列后,默认情况下会将其设置为selected = false,这会导致它尝试成为第一响应者 . 这是我的一个愚蠢的错误 .

    这就是我打算做的事情:

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    
        if selected {
            self.textfield.becomeFirstResponder()
        }
    }
    
  • 2

    我认为 dequeue 代码真的会持续这么长时间,除非你花了这么长时间 . 但要调试它,您必须考虑以下几点:

    • NSLog不是用于检查 dequeue 持续时间的可靠计时器 . 您应该使用以下代码准确计算时间:

    let start = CACurrentMediaTime()
    让cell = tableView.dequeueReusableCell(withIdentifier:cellid,for:indexPath)为! TextfieldTableViewCell
    let finish = CACurrentMediaTime()
    打印("dequeue time:(finish - start)")

    • 如果 dequeue 时间可以接受,则表明您的性能问题不是由它引起的 .

    • 如果 dequeue 时间仍然不可接受 . 理所当然的一个原因是你的tableview只有四行,并且没有一行高于tableview,所以tableview不会使用缓冲区中的单元格,而是从下往上创建一个单元格 . 此操作比使用缓冲区中的单元更耗时 . 但是这个过程是不可避免的,因为每个使用tableview的应用都会遇到它 . 因此,您应该考虑您的模拟器(假设您使用的是模拟器)是否太慢而无法运行您的应用程序 . 因为模拟器和真正的iPhone之间的速度是完全不同的 .

相关问题