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

原来的post

我们最近已经将我们的应用程序转换为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 } 

标题单元格

 class HeaderSectionCell: UITableViewCell { @IBOutlet var labelOne: UITextView! @IBOutlet var labelTwo: UITextView! @IBOutlet var textView: UITextView! } 

模拟器CPU使用率在100%

CPU挂钩


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

暂停时暂停显示我们在这里


以下是iOS正在循环下的一些例程。

在这里输入图像说明

在这里输入图像说明

最后,我们的Swift调用dequeueReusableCellWithIdentifier() 在这里输入图像说明

这个特殊的悬挂实例是从函数tableView(tableView: UITableView, viewForHeaderInSection section: Int) ,但我们也挂在对tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)的调用中,同样的问题。

我试过在storyboard编辑器中使用单元格属性,但没有任何东西与其他视图工作正常。

编辑

看起来在Foundation和libobjc.A.dylib之间有一个无限循环,在对dequeReusableCellWithIdentifier()的调用之下。 我最终确定了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) 

堆栈跟踪的另一个暂停之后的顶部:

 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 

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

这是一个string本地化问题。 UITableViewCell包含的UITextField具有Text属性的非空值,在UITextView的本地化属性中没有英文检查。

检查English解决了这个问题。

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

我的解决scheme与styler1972相似。

就我而言,我是从Swift 1.2升级到Swift 2.0的组合Swift / Objective-C项目。 在升级到Swift 2.0之前,该应用在iOS 9上运行良好。 升级到Swift 2.0之后,从Table View Cell Accessory Push到View Controller时,应用程序将进入无限循环。 在模拟器中运行应用程序,然后在被无限循环捕获时暂停它,使我处于[NSLocalizableString length](这导致我到这个post)。

我的修复是要做到以下几点。

  • 从en.lproj目录中删除Main.storyboard文件。
  • 除去en.lproj目录,包括InfoPlist.strings文件。
  • 将Main.storyboard放置在根项目目录中。
  • 更新项目以反映上述更改。
  • 在“信息/本地化”下的项目设置中,删除所有设置。
  • 清理生成目录(好措施)。
  • 清洁版本(为了好的措施)。
  • build立并运行。

无限循环不再发生。

确保以后备份您的项目文件以恢复本地化文件。

  • 在“项目设置”中的“本地化”中,除了项目开发语言(对我而言,这是英语),请删除所有本地化。
  • 清理并运行。 在这一点上,你不应该看到这个错误了。
  • 添加上面删除的本地化,并从备份恢复本地化。

使用dequeueReusableHeaderFooterViewWithIdentifier而不是dequeueReusableCellWithIdentifier

您正试图加载单元格viewForHeaderInSection这也是不正确的。

编辑:

 class HeaderSectionView: UITableViewHeaderFooterView { @IBOutlet var labelOne: UITextView! @IBOutlet var labelTwo: UITextView! @IBOutlet var textView: UITextView! } 

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

不要忘记注册你的HeaderSectionView

 tableView.registerNib(UINib(nibName: "HeaderSectionView", bundle:nil), forHeaderFooterViewReuseIdentifier: "SectionHeader")