问题
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
回答1:
Here's A Few Things To Check
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 inOnBindingContextChanged()
, rather than in the ViewCell's constructor. I added some sample code below that shows how to implement theListViewCachingStrategy.RecycleElement
strategy using a custom ViewCell.- If you are subscribing an Event Handler for the ViewCell (to add a Context Action for example), make sure to subscribe the Event Handler in the
OnAppearing()
method of the ViewCell class and unsubscribe the Event Handler in theOnDisappearing()
method of the ViewCell class. I've included a comment in the example ViewCell code below.
ListView Using RecycleElement
ListView = new ListView(ListViewCachingStrategy.RecycleElement)
{
DataTemplate(typeof(CustomViewCell))
};
ViewCell
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
}
}
ViewCell Model
public class MyModel
{
[PrimaryKey]
public int ID { get; set; }
public string Text { get; set; }
}
来源:https://stackoverflow.com/questions/34249122/xamarin-forms-listview-cachingstrategy