titanium-sdk
titanium-sdk copied to clipboard
iOS: ListView with many AttributedStrings crashes
Description
Using a ListView with many attributedStrings will crash the iOS app. Hard crash with crashlog.txt
Reproducible sample
const win = Ti.UI.createWindow({});
function addListView() {
var listView = Ti.UI.createListView({
templates: {
test: {
childTemplates: [{
type: 'Ti.UI.View',
childTemplates: [{
type: 'Ti.UI.Label',
bindId: 'label',
properties: {
color: 'black',
bindId: 'label'
}
}],
properties: {
width: Ti.UI.FILL,
height: 100,
cardUseCompatPadding: true,
backgroundColor: 'white'
}
}]
}
},
defaultItemTemplate: 'test'
});
var section = Ti.UI.createListSection();
var items = [];
for (let i = 0; i < 700; i++) {
var txt = "test text test text test text test text test text test text test text test text test text test text";
var attr = Titanium.UI.createAttributedString({
text: txt,
attributes: [{
type: Titanium.UI.ATTRIBUTE_PARAGRAPH_STYLE,
range: [0, txt.length],
value: {
lineSpacing: 0,
lineHeightMultiple: 0.8,
lineBreakMode: Titanium.UI.ATTRIBUTE_LINE_BREAK_BY_WORD_WRAPPIN
}
}]
});
items.push({
label: {
attributedString: attr
},
template: 'test'
})
}
section.setItems(items);
listView.sections = [section];
win.add(listView);
}
win.addEventListener('open', function() {
addListView();
})
win.open();
Steps to reproduce
- start app
- scroll down
Platform
iOS
SDK version you are using
10.1.1
@m1ga It does not crash for me (iOS 15.4, iPhone 13 Pro). It may be an out-of-resource issue for some devices, which may even reproduce on native apps, since you load multiple hundred cells at the same time instead of lazy-loading them. If it also reproduces with less cells (~100), it's definitely a proxy issue in Titanium.
In general, I would keep it open for now so I can reproduce it. Any guidance on your device config?
Thanks for the feedback @hansemannn ! In this case I load all of them at once. In my real app I lazy load the elements.
The crashlog is from a simulator iPhone 12 Pro - Runtime: iOS 15.4
but I also had this on my device (iPhone 7 :blush: ) but on an iPhone 13 Max Pro (device) we couldn't reproduce it.
I was hoping the crashlog would just show an "easy to fix" line in the code :smile: Without the AttributedString it works fine btw! Just using the AttributedString makes it crash after scrolling down
Ah, I remember that the last time i was looking into JSCore crashes they were also related to attributed strings in a list view. I never figured out what's so special about them. For some reason their underlying JSCore object is garbage collected before it is used in the actual list view rendering which then causes the crash. But thanks for remembering me about this, it's a good place to start looking for the next debug session.
As Jan is currently looking into it: It's notable that the Ti.UI.AttributedString
is the only case (I can think of) where a proxy is passed as a property value inside a list item template. Therefore it seems like it needs some special guards to retain the proxy and prevent it from being deallocated when being temporary recycled by the UITableView
cell logic.
In addition, iOS 11 added the performBatchUpdates:
API to update multiple cell items at the same time - something thats done very manually right now using multiple mutex-locks and main-thread jumps.
@m1ga I cannot reproduce this with any recent Simulator. Any recent config where it still reproduces?
I'll check it tomorrow and try to reproduce it again