【问题标题】:Xamarin Forms ListView CachingStrategyXamarin Forms ListView 缓存策略
【发布时间】:2016-03-18 21:02:10
【问题描述】:

我最近在 Xamarin Forms 应用程序中测试了 CachingStrategyListView,列表中有 1000 个项目。正在从ViewCell 的数据模板创建列表项。我尝试对CachingStrategy 使用RecycleElement 选项。

当我使用 Xamarin Profiler 为部署在 Xamarin Anroid Player(模拟器)上的 Android 应用程序进行分析时,我注意到当我滚动列表时内存分配不会增加(在分配摘要选项卡上)。但是,当我在模拟器上对 iPhone 应用程序进行分析时,我注意到分配摘要选项卡上没有显示任何数据。因此,我在滚动列表时捕获了一些快照,并注意到每当我滚动列表(向上或向下)时,内存分配都会不断增加。

为什么RecycleElement 不适用于 iOS (iPhone)?

我正在使用 Mac 进行开发。 这是我的工具:

=== Xamarin Studio ===

版本 5.10.1(构建 3) 安装UUID:7ae992a3-b710-4297-ba1d-0c519fbb2ea8 运行: 单声道 4.2.1 (显式/6dd2d0d) GTK+ 2.24.23(罗利主题)

Package version: 402010102

=== Xamarin.Profiler ===

版本:0.24.0.0 位置:/Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler

=== 苹果开发者工具 ===

Xcode 7.1.1 (9081) 构建 7B1005

=== Xamarin.iOS ===

版本:9.2.1.54(企业版) 哈希:eb4c1ef 分支:主 构建日期:2015-12-01 02:12:30-0500

=== Xamarin.Android ===

版本:6.0.0.34(企业版) Android SDK:/Users/haider/Library/Developer/Xamarin/android-sdk-macosx 支持的安卓版本: 4.0.3(API 级别 15) 4.4(API 级别 19) 5.0(API 级别 21) 5.1(API 级别 22) 6.0(API 级别 23)

SDK 工具版本:24.4.1 SDK平台工具版本:23.1 rc1 SDK 构建工具版本:23.0.2

Java SDK:/usr java版本“1.7.0_71” Java(TM) SE 运行时环境 (build 1.7.0_71-b14) Java HotSpot(TM) 64 位服务器 VM(内部版本 24.71-b01,混合模式)

=== Xamarin Android 播放器 ===

版本:0.6.5 位置:/Applications/Xamarin Android Player.app

=== Xamarin.Mac ===

版本:2.4.0.109(入门版)

=== 构建信息 ===

版本号:510010003 Git 修订:f2021a209d66d49cbc0649a6d968b29040e57807 构建日期:2015-12-01 10:43:40-05 Xamarin 插件:dfd4f5103e8951edbc8ac24480b53b53c55e04ff 构建通道:monodevelop-lion-cycle6-baseline

=== 操作系统 ===

Mac OS X 10.11.1 Darwin Haiders-MacBook-Pro.local 15.0.0 达尔文内核版本 15.0.0 2015 年 9 月 19 日星期六 15:53:46 PDT 根:xnu-3247.10.11~1/RELEASE_X86_64 x86_64

【问题讨论】:

  • 这是一个很好的问题。我不确定,但也许这是一个错误。你在 Bugzilla 上发布了吗?
  • 没有。我猜他们在提问时提到了 StackOverflow。
  • 嗨海德尔!如果您对以下解决方案有任何后续问题,请告诉我!如果您没有任何后续问题,请将此问题标记为已回答,以便将来有类似问题的开发人员帮助他们!

标签: ios xamarin xamarin.forms xamarin-studio xamarin.mac


【解决方案1】:

这里有几件事要检查

  1. 在 Xamarin Profiler 中,确保您只查找自定义 ViewCell 类,并拍摄多个快照以触发垃圾收集器。如果 ViewCell 的数量没有增加,则可能是其他原因导致内存泄漏。如果 ViewCell 的数量在增加,请转到下面的建议 2 和 3。 Xamarin Profiler ViewCell example

  2. 在 ViewCell 代码中,确保覆盖 OnBindingContextChanged() 并将控件的属性设置在 OnBindingContextChanged() 中,而不是在 ViewCell 的构造函数中。我在下面添加了一些示例代码,展示了如何使用自定义 ViewCell 实现 ListViewCachingStrategy.RecycleElement 策略。

  3. 如果您正在为 ViewCell 订阅事件处理程序(例如添加 Context Action),请确保在 ViewCell 类的 OnAppearing() 方法中订阅事件处理程序并在 @987654328 中取消订阅事件处理程序@ViewCell 类的方法。我在下面的示例 ViewCell 代码中添加了注释。

ListView 使用 RecycleElement

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
    }
}

ViewCell 模型

public class MyModel
{
    [PrimaryKey]
    public int ID { get; set; }

    public string Text { get; set; }
}

【讨论】:

  • 为什么不想使用绑定?
  • 嗨@François!使用 ListViewCachingStrategy.RecycleElement 时,您需要通过覆盖 ViewCell 的 OnAppearing 出现方法来设置分配绑定。这确保了当 ViewCell 滚动离开屏幕时数据被回收。这是 Xamarin 文档的链接:developer.xamarin.com/guides/xamarin-forms/user-interface/…
  • Tks 但它确实说“这可以通过使用数据绑定来显示单元格数据来完成”。然后介绍您的方法作为替代方法。
  • 这个例子仍然使用数据绑定,只是不是传统的使用 SetBinding 方法。 ViewCell 通过引用 BindingContext 将数据绑定到 OnAppearing 中的模型。在上面的示例中,我们需要为每个 ViewCell 分配一个 EventHandler,并且我们需要确保在 ViewCell 滚出屏幕时取消订阅 EventHandler,因为如果我们不取消订阅 EventHandler,我们将体验到内存泄漏。正确分配和取消分配 EventHandler 的唯一方法是重写 OnAppearing 和 OnDisappearing 方法。
  • 这是我在遇到问题时一直在寻找的答案。但他们应该修复绑定,而不是我们处理它。
猜你喜欢
  • 2018-10-13
  • 1970-01-01
  • 2010-10-06
  • 2017-01-05
  • 1970-01-01
  • 2012-09-05
  • 2020-08-03
  • 2011-11-12
  • 2011-01-18
相关资源
最近更新 更多