ORIGINAL POST
We have recently converted our app to Swift 2.0, and iOS9. One strange issue I am seeing is that calls to tableView.dequeueReusableCellWithIdentifier() cause the app to hang in the simulator.
The code
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
//hangs on the line below
let headersection: HeaderSectionCell = tableView.dequeueReusableCellWithIdentifier("SectionHeader") as! HeaderSectionCell
...
return headersection
}
The header cell
class HeaderSectionCell: UITableViewCell {
@IBOutlet var labelOne: UITextView!
@IBOutlet var labelTwo: UITextView!
@IBOutlet var textView: UITextView!
}
The simulator CPU usage pegs at 100%
After hitting pause in Xcode, it shows me its hanging on this Swift function.
Here are some of the routines where iOS is looping under the covers.
Finally, our Swift call to dequeueReusableCellWithIdentifier()
This particular hanging instance is from the function tableView(tableView: UITableView, viewForHeaderInSection section: Int)
, but we're also hanging inside of a call to tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)
, with the same issue.
I've tried playing around with the cell properties in storyboard editor, but nothing sticks out as anything different from other views that are working fine.
EDIT
It appears that there is an infinite loop between Foundation and libobjc.A.dylib, underneath that call to dequeReusableCellWithIdentifier(). I ended up making sure Foundation was imported before any other framework, and abstracted the offending UITableViewCell into its own class (was being reused). The original call in question is now working, but there is another one that is still looping under the Swift covers that I am working to figure out.
Hitting pause in the infinite loop puts me in the same assembly stack locations:
Top of stack trace after pause:
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)
Top of stack trace after another pause:
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
It's just looping back and forth between these two lower level routines, consuming 100% of the simulator CPU.
Make sure to backup your project files to restore the localization files later on.
My solution was similar to styler1972's.
In my case, I was upgrading a combination Swift / Objective-C project from Swift 1.2 to Swift 2.0. The app ran fine on iOS 9 prior to the upgrade to Swift 2.0. After the upgrade to Swift 2.0 the app would enter an infinite loop when segueing from a Table View Cell Accessory Push to a View Controller. Running the app in the simulator, then pausing it when caught in the infinite loop left me at [NSLocalizableString length] (which led me to this post).
My fix was to do the following.
Infinite loop no longer occurs.
It was a String localization issue. The UITableViewCell contained UITextField with a non-empty value for the Text property, that didn't have English checked in the Localization properties of the UITextView.
Checking
English
fixed the issue.What a pain! Go figure, why not infinitely loop instead of throw an intelligible error?
use
dequeueReusableHeaderFooterViewWithIdentifier
instead ofdequeueReusableCellWithIdentifier
You are trying to load cell in viewForHeaderInSection which is also not correct.
Edited:
and
Do not forget to register your HeaderSectionView as