Titanium JIRA Archive
Appcelerator Community (AC)

[AC-3143] Rows are not being reused even though className is set

GitHub Issuen/a
TypeBug
Priorityn/a
StatusClosed
ResolutionFixed
Resolution Date2011-10-04T15:01:28.000+0000
Affected Version/sn/a
Fix Version/sn/a
ComponentsTitanium SDK & CLI
Labelsios, tableview, ui
ReporterGetGlue
AssigneeKevin Whinnery
Created2011-09-28T13:13:32.000+0000
Updated2016-03-08T07:48:12.000+0000

Description

While profiling our app I noticed that scrolling through the stream continues to generate new views rather than reusing existing ones. These rows do in fact have classNames set, and when the table is cleared, all the views are indeed garbage collected, so I do not believe it is an issue of external references being kept. Also of interest, the # of transitory instances also continues to rise, suggesting that the rows are being continuously garbage collected and recreated (potentially as a result of continuous setData calls). Video of the issue: http://cl.ly/1M3L2T2y2k3k1q1y3g2Y Factory method used to generate these rows: https://gist.github.com/7bd7d37b056562eb9962 Not that to page in new rows, they are added to the main tableViewSection, and then setData is called on the table with the entire array of sections again

Comments

  1. Anthony Decena 2011-10-04

       var win = Ti.UI.createWindow();
       
       function createRow(c) {
       		var row = Ti.UI.createTableViewRow();
       	row.selectedBackgroundColor = '#fff';
       	row.height = 100;
       	row.className = 'datarow';
       	row.clickName = 'row';
       
       	var photo = Ti.UI.createView({
       		backgroundImage:'user.png',
       		top:5,
       		left:10,
       		width:50,
       		height:50,
       		clickName:'photo'
       	});
       	row.add(photo);
       
       
       	var user = Ti.UI.createLabel({
       		color:'#576996',
       		font:{fontSize:16,fontWeight:'bold', fontFamily:'Arial'},
       		left:70,
       		top:2,
       		height:30,
       		width:200,
       		clickName:'user',
       		text:'Fred Smith '+c
       	});
       
       	row.filter = user.text;
       	row.add(user);
       
       	var fontSize = 16;
       	if (Titanium.Platform.name == 'android') {
       		fontSize = 14;
       	}
       	var comment = Ti.UI.createLabel({
       		color:'#222',
       		font:{fontSize:fontSize,fontWeight:'normal', fontFamily:'Arial'},
       		left:70,
       		top:21,
       		height:50,
       		width:200,
       		clickName:'comment',
       		text:'Got some fresh fruit, conducted some business, took a nap'
       	});
       	row.add(comment);
       
       	var calendar = Ti.UI.createView({
       		backgroundImage:'/KS_nav_ui.png',
       		bottom:2,
       		left:70,
       		width:32,
       		clickName:'calendar',
       		height:32
       	});
       	row.add(calendar);
       
       	var button = Ti.UI.createView({
       		backgroundImage:'KS_nav_views.png',
       		top:35,
       		right:5,
       		width:36,
       		clickName:'button',
       		height:34
       	});
       	row.add(button);
       
       	var date = Ti.UI.createLabel({
       		color:'#999',
       		font:{fontSize:13,fontWeight:'normal', fontFamily:'Arial'},
       		left:105,
       		bottom:5,
       		height:20,
       		width:100,
       		clickName:'date',
       		text:'posted on 3/11'
       	});
       	row.add(date);
       	return row;
       }
       
       var data = [];
       var lastRow = 10;
       for (var c=0;c<lastRow;c++)
       {
       	var row = createRow(c);
       	data.push(row);
       }
       
       var tableView = Ti.UI.createTableView({
       	data: data
       });
       
       win.add(tableView);
       
       var navActInd = Titanium.UI.createActivityIndicator();
       win.setRightNavButton(navActInd);
       
       var updating = false;
       var loadingRow = Ti.UI.createTableViewRow({title:"Loading..."});
       
       function beginUpdate()
       {
       	updating = true;
       	navActInd.show();
       
       	tableView.appendRow(loadingRow);
       
       	// just mock out the reload
       	setTimeout(endUpdate,2000);
       }
       
       function endUpdate()
       {
       	updating = false;
       
       	tableView.deleteRow(lastRow,{animationStyle:Titanium.UI.iPhone.RowAnimationStyle.NONE});
       
       	// simulate loading
       	for (var c=lastRow;c<lastRow+10;c++)
       	{
       		tableView.appendRow(createRow(c),{animationStyle:Titanium.UI.iPhone.RowAnimationStyle.NONE});
       	}
       	lastRow += 10;
       
       	// just scroll down a bit to the new rows to bring them into view
       	tableView.scrollToIndex(lastRow-9,{animated:true,position:Ti.UI.iPhone.TableViewScrollPosition.BOTTOM});
       
       	navActInd.hide();
       }
       
       var lastDistance = 0; // calculate location to determine direction
       
       tableView.addEventListener('scroll',function(e)
       {
       	var offset = e.contentOffset.y;
       	var height = e.size.height;
       	var total = offset + height;
       	var theEnd = e.contentSize.height;
       	var distance = theEnd - total;
       
       	// going down is the only time we dynamically load,
       	// going up we can safely ignore -- note here that
       	// the values will be negative so we do the opposite
       	if (distance < lastDistance)
       	{
       		// adjust the % of rows scrolled before we decide to start fetching
       		var nearEnd = theEnd * .75;
       
       		if (!updating && (total >= nearEnd))
       		{
       			beginUpdate();
       		}
       	}
       	lastDistance = distance;
       });
       
       
       win.open();
       
  2. GetGlue 2011-10-04

    Does this also produce the same issue? If it does it goes against my hunch that it was setData causing the issue, since you are paging in new rows with appendRow
  3. Anthony Decena 2011-10-04

  4. Jude Osborn 2011-10-20

    Glad to see this is being considered. Table performance is nearly a deal breaker for us as far as using Titanium with our apps.

JSON Source