I have recently tested the CachingStrategy
for a ListView
in a Xamarin Forms App with 1000 items in the list. List items are being created from a data template of ViewCell
. I Tried using RecycleElement
option for CachingStrategy
.
When I did profiling, using Xamarin Profiler, for Android App deployed on Xamarin Anroid Player (emulator) I noticed that when I scroll through the list the memory allocation doesn't increase (on allocations summary tab). But, when I did profiling for iPhone App on emulator, I noticed that no data is being displayed on Allocations Summary tab. So I captured some snapshots while scrolling through the list and noticed whenever I scroll through the list (up or down), the memory allocation keeps increasing.
Why RecycleElement
is not working for iOS (iPhone)?
I am using Mac for development. Here are my tools:
=== Xamarin Studio ===
Version 5.10.1 (build 3) Installation UUID: 7ae992a3-b710-4297-ba1d-0c519fbb2ea8 Runtime: Mono 4.2.1 (explicit/6dd2d0d) GTK+ 2.24.23 (Raleigh theme)
Package version: 402010102
=== Xamarin.Profiler ===
Version: 0.24.0.0 Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler
=== Apple Developer Tools ===
Xcode 7.1.1 (9081) Build 7B1005
=== Xamarin.iOS ===
Version: 9.2.1.54 (Enterprise Edition) Hash: eb4c1ef Branch: master Build date: 2015-12-01 02:12:30-0500
=== Xamarin.Android ===
Version: 6.0.0.34 (Enterprise Edition) Android SDK: /Users/haider/Library/Developer/Xamarin/android-sdk-macosx Supported Android versions: 4.0.3 (API level 15) 4.4 (API level 19) 5.0 (API level 21) 5.1 (API level 22) 6.0 (API level 23)
SDK Tools Version: 24.4.1 SDK Platform Tools Version: 23.1 rc1 SDK Build Tools Version: 23.0.2
Java SDK: /usr java version "1.7.0_71" Java(TM) SE Runtime Environment (build 1.7.0_71-b14) Java HotSpot(TM) 64-Bit Server VM (build 24.71-b01, mixed mode)
=== Xamarin Android Player ===
Version: 0.6.5 Location: /Applications/Xamarin Android Player.app
=== Xamarin.Mac ===
Version: 2.4.0.109 (Starter Edition)
=== Build Information ===
Release ID: 510010003 Git revision: f2021a209d66d49cbc0649a6d968b29040e57807 Build date: 2015-12-01 10:43:40-05 Xamarin addins: dfd4f5103e8951edbc8ac24480b53b53c55e04ff Build lane: monodevelop-lion-cycle6-baseline
=== Operating System ===
Mac OS X 10.11.1 Darwin Haiders-MacBook-Pro.local 15.0.0 Darwin Kernel Version 15.0.0 Sat Sep 19 15:53:46 PDT 2015 root:xnu-3247.10.11~1/RELEASE_X86_64 x86_64
In the Xamarin Profiler, ensure that you are only looking for the custom ViewCell class, and take multiple snapshots to trigger the garbage collector. It may be something else that is causing the memory leak if the number of ViewCells is not increasing. If the number of ViewCells is increasing, move on to suggestions 2 & 3, below. Xamarin Profiler ViewCell example
In the ViewCell code, make sure to override OnBindingContextChanged()
and set the controls' properties in OnBindingContextChanged()
, rather than in the ViewCell's constructor. I added some sample code below that shows how to implement the ListViewCachingStrategy.RecycleElement
strategy using a custom ViewCell.
OnAppearing()
method of the ViewCell class and unsubscribe the Event Handler in the OnDisappearing()
method of the ViewCell class. I've included a comment in the example ViewCell code below.ListView = new ListView(ListViewCachingStrategy.RecycleElement)
{
DataTemplate(typeof(CustomViewCell))
};
public class CustomViewCell : ViewCell
{
Label _myLabel;
MenuItem _deleteAction;
public CustomViewCell()
{
_myLabel = new Label();
View = _myLabel;
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
_myLabel.Text = "";
var item = BindingContext as MyModel;
if (item != null)
{
_myLabel.Text = item.Text;
}
}
protected override void OnAppearing()
{
base.OnAppearing();
//Subscribe ViewCell Event Handlers
_deleteAction.Clicked += HandleDeleteClicked;
ContextActions.Add(_deleteAction);
}
protected override void OnDisappearing()
{
base.OnDisappearing();
//Unsubscribe ViewCell Event Handlers
_deleteAction.Clicked -= HandleDeleteClicked;
ContextActions.Remove(_deleteAction);
}
void HandleDeleteClicked(object sender, EventArgs e)
{
//Code to handle when the delete action is tapped
}
}
public class MyModel
{
[PrimaryKey]
public int ID { get; set; }
public string Text { get; set; }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With