titanium-sdk icon indicating copy to clipboard operation
titanium-sdk copied to clipboard

iOS: ListView with many AttributedStrings crashes

Open m1ga opened this issue 2 years ago • 2 comments

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 avatar May 10 '22 14:05 m1ga

@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?

hansemannn avatar Jul 01 '22 10:07 hansemannn

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

m1ga avatar Jul 01 '22 11:07 m1ga

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.

janvennemann avatar Dec 09 '22 12:12 janvennemann

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.

hansemannn avatar Jan 03 '23 09:01 hansemannn

@m1ga I cannot reproduce this with any recent Simulator. Any recent config where it still reproduces?

hansemannn avatar Jan 03 '23 16:01 hansemannn

I'll check it tomorrow and try to reproduce it again

m1ga avatar Jan 03 '23 20:01 m1ga