ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – 如何修复由lambda事件处理程序引起的GC循环?

2019-05-17 15:55:12  阅读:441  来源: 互联网

标签:c garbage-collection mono xamarin-ios xamarin


通过Mark Probst和Rodrigo Kumpera观察Advanced Memory Management,我学习了新技术,例如分析Mono GC和使用WeakReference.

然而,我仍然不明白如何从第28分钟“修复”拼图2:

public class CustomButton : UIButton {
    public CustomButton () { }
}

public class Puzzle2Controller : UIViewController
{
    public override void ViewDidLoad ()
    {
        var button = new CustomButton ();
        View.Add (button);
        button.TouchUpInside += (sender, e) =>
            this.RemoveFromParentViewController ();
    }
}

控制器保存一个ref to按钮,该按钮保存一个ref事件处理程序,该处理程序将ref保存到控制器.

打破循环的一种方法是使按钮无效.
另一种方法是分离处理程序(但我们必须抛弃使用lamdas).

是否有其他/更优雅/方式来打破这个循环?我们能以某种方式将WeakReference粘贴在这里吗?

谢谢.

编辑:在这种情况下,按钮甚至不是一个字段.但是还有一个周期,不是吗?它位于Controller的View的子视图中.我们必须清除它们吗?我糊涂了.

解决方法:

在垃圾收集环境中,循环通常不是问题 – 我必须从问题中假设这在单调处有些不同?编辑:不,我在这里的假设仍然有效 – 在你连接到它的视频中的7:50表示“扫描”丢弃了一个循环.

一旦整个周期变得无法到达,周期通常可以完全销售.这将是参考计数系统中的问题.

然而!关于你的问题 – 按钮(一旦添加)是否知道控制器?如果是这样,你可以从发件人到达那里:

button.TouchUpInside += (sender, e) =>
            ((UIButton)sender).Parent.RemoveFromParentViewController();

此lambda现在不涉及捕获的变量,并且不涉及捕获上下文;它没有任何对控制器的引用 – 实际上大多数编译器会将它作为单个静态处理程序而不是每次使用的处理程序,因此它在委托创建方面也更有效.

具体来说是单音的背景,然后是的,你需要使用WeakReference< T>:

var controller = new WeakReference<Puzzle2Controller>(this);
button.TouchUpInside += (sender, e) => {
    var parent = controller.Object;
    if(parent != null) parent.RemoveFromParentViewController();
};

标签:c,garbage-collection,mono,xamarin-ios,xamarin
来源: https://codeday.me/bug/20190517/1122175.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有