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

时间:2017-07-26 05:30:43

标签: ios swift uitableview swift3

出现一个单元格需要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] 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]从公共有效用户设置中读取。

     

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 :(得分:2)

  

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-在您的环境变量集OS_ACTIVITY_MODE

中设置disable

enter image description here

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

答案 1 :(得分: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 :(得分:0)

我认为这段代码没有任何问题。我不认为dequeue代码真的会持续很长时间,除非你在代码中遗漏了一些重要问题。如果您的表格视图如您所说的那样简单,那就不会花这么长时间。但要调试它,你必须考虑以下几点:

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

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

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

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