tableView.dequeueReusableCellWithIdentifier()导致应用程序挂起

sty*_*972 5 uitableview ios swift ios9 swift2

原始邮政

我们最近将我们的应用程序转换为Swift 2.0和iOS9.我看到的一个奇怪问题是调用tableView.dequeueReusableCellWithIdentifier()会导致应用程序在模拟器中挂起.


代码

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    //hangs on the line below
    let headersection: HeaderSectionCell = tableView.dequeueReusableCellWithIdentifier("SectionHeader") as! HeaderSectionCell 

    ...

    return headersection
}
Run Code Online (Sandbox Code Playgroud)

标题单元格

class HeaderSectionCell: UITableViewCell {

    @IBOutlet var labelOne: UITextView!
    @IBOutlet var labelTwo: UITextView!
    @IBOutlet var textView: UITextView!

}
Run Code Online (Sandbox Code Playgroud)

模拟器CPU使用率为100%

CPU挂钩


在Xcode中暂停后,它显示了它挂在这个Swift函数上.

悬挂时暂停让我们看到这里


以下是iOS在封面下循环的一些例程.

在此输入图像描述

在此输入图像描述

最后,我们的Swift调用dequeueReusableCellWithIdentifier() 在此输入图像描述

这个特殊的悬挂实例来自函数tableView(tableView: UITableView, viewForHeaderInSection section: Int),但我们也挂在调用内部,tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)同样的问题.

我已经尝试过在故事板编辑器中使用单元格属性,但没有什么能与其他正常工作的视图有所不同.

编辑

在调用dequeReusableCellWithIdentifier()之下,Foundation和libobjc.A.dylib之间似乎存在无限循环.我最终确保在任何其他框架之前导入Foundation,并将违规的UITableViewCell抽象到自己的类中(正在被重用).有问题的原始呼叫现在正在运行,但还有另一个仍然在我正在努力解决的Swift封面下循环.

在无限循环中达到暂停会使我进入相同的汇编堆栈位置:

暂停后堆栈跟踪的顶部:

libobjc.A.dylib`objc_msgSend:
    0x107f6a800 <+0>:   testq  %rdi, %rdi
    0x107f6a803 <+3>:   jle    0x107f6a850               ; <+80>
    0x107f6a805 <+5>:   movq   (%rdi), %r11
    0x107f6a808 <+8>:   movq   %rsi, %r10
    0x107f6a80b <+11>:  andl   0x18(%r11), %r10d
    0x107f6a80f <+15>:  shlq   $0x4, %r10
    0x107f6a813 <+19>:  addq   0x10(%r11), %r10
    0x107f6a817 <+23>:  cmpq   (%r10), %rsi
    0x107f6a81a <+26>:  jne    0x107f6a820               ; <+32>
->  0x107f6a81c <+28>:  jmpq   *0x8(%r10)
Run Code Online (Sandbox Code Playgroud)

在另一个暂停之后堆栈跟踪:

Foundation`-[NSLocalizableString length]:
    0x1071c5cbc <+0>:  pushq  %rbp
    0x1071c5cbd <+1>:  movq   %rsp, %rbp
->  0x1071c5cc0 <+4>:  movq   0x80461(%rip), %rax       ; NSLocalizableString._developmentLanguageString
    0x1071c5cc7 <+11>: movq   (%rdi,%rax), %rdi
    0x1071c5ccb <+15>: movq   0x7436e(%rip), %rsi       ; "length"
    0x1071c5cd2 <+22>: popq   %rbp
    0x1071c5cd3 <+23>: jmpq   *0x8ea77(%rip)            ; (void *)0x0000000107f6a800: objc_msgSend
Run Code Online (Sandbox Code Playgroud)

它只是在这两个较低级别的例程之间来回循环,消耗100%的模拟器CPU.

sty*_*972 13

这是一个String本地化问题.UITableViewCell包含UITextField,其Text属性的值为非空值,未在UITextView的Localization属性中检查英语.

检查English修复了问题.

太痛苦了!去图,为什么不能无限循环而不是抛出可理解的错误?

  • 经过几个小时试图弄清楚为什么我无法释放可重复使用的细胞,我几乎要跳出窗外.然后,我偶然发现了你的帖子.我心里想:"这不可能是问题/解决办法" - 很低,并且看不出问题.也许我在发行说明中错过了这个:"如果你没有选择本地化,你将进入无限循环,但我们不会告诉你." 谢谢! (2认同)

Jus*_*itz 5

我的解决方案类似于styler1972.

在我的例子中,我正在将Swift/Objective-C项目从Swift 1.2升级到Swift 2.0.在升级到Swift 2.0之前,应用程序在iOS 9上正常运行.升级到Swift 2.0后,当从表视图单元附件推送到视图控制器时,应用程序将进入无限循环.在模拟器中运行应用程序,然后在无限循环中捕获时将其保留在[NSLocalizableString length](这导致我发布此帖子).

我的解决方法是执行以下操作.

  • 从en.lproj目录中删除Main.storyboard文件.
  • 删除en.lproj目录,包括InfoPlist.strings文件.
  • 将Main.storyboard放在根项目目录中.
  • 更新项目以反映上述更改.
  • 在"信息/本地化"下的项目设置中,删除所有设置.
  • 清理构建目录(以获得良好的衡量标准).
  • 清洁构建(为了好的措施).
  • 建立并运行.

无限循环不再发生.