Xamarin.ios 为什么MonoTouch不垃圾收集我的自定义UIButton,除非我调用button.RemoveFromSuperview()?
似乎有东西引用了我的自定义按钮,Xamarin.ios 为什么MonoTouch不垃圾收集我的自定义UIButton,除非我调用button.RemoveFromSuperview()?,xamarin.ios,Xamarin.ios,似乎有东西引用了我的自定义按钮,MyButton(它继承自UIButton),导致它不会被垃圾收集,除非我将其从superview中删除。这反过来会导致它所在的视图控制器也无法最终确定和收集 在我的示例中,我有一个自定义按钮,但在视图控制器上也有一个标准的ui按钮,它不需要从superview中删除即可收集。有什么区别?看起来很像我 请参阅此代码。为了举例说明,删除了不相关的行。关于示例,需要注意的一些事项: -MyButton相当空。只是一个构造函数,没有其他被重写的内容 -想象一下MyVie
MyButton
(它继承自UIButton
),导致它不会被垃圾收集,除非我将其从superview中删除。这反过来会导致它所在的视图控制器也无法最终确定和收集
在我的示例中,我有一个自定义按钮,但在视图控制器上也有一个标准的ui按钮
,它不需要从superview中删除即可收集。有什么区别?看起来很像我
请参阅此代码。为了举例说明,删除了不相关的行。关于示例,需要注意的一些事项:
-MyButton
相当空。只是一个构造函数,没有其他被重写的内容
-想象一下MyViewController
在UINavigationController
-LoadView()
只需创建按钮,为每个按钮连接一个事件并将其添加到视图中
-触摸\u按钮
会将另一个MyViewController
推至导航控制器
-当在viewdide()中将视图控制器弹出导航控制器时,我正在进行一些参考清理。
-在CleanUpRefs()
中,您将看到我必须从superview中删除\u myButton
,以便对所有对象进行垃圾收集<代码>\另一方面,不需要删除按钮
-我希望在从导航控制器弹出时收集整个MyViewController,包括所有子视图,但注释掉\u myButton。RemoveFromSuperview()
会阻止这种情况发生
public class MyViewController : UIViewController
{
private UIButton _button;
private MyButton _myButton;
private MyViewController _nextController;
public override void LoadView()
{
base.LoadView();
_button = UIButton.FromType(UIButtonType.RoundedRect);
_button.TouchUpInside += PushNewController;
View.AddSubview(_button);
_myButton = new MyButton();
_myButton.TouchUpInside += MyButtonTouched;
View.AddSubview(_myButton);
}
private void PushNewController(object sender, EventArgs e)
{
_nextController = new MyViewController();
NavigationController.PushViewController(_nextController, true);
}
private void MyButtonTouched(object sender, EventArgs e)
{
Console.WriteLine("MyButton touched");
}
public void CleanUpRefs()
{
//_button.RemoveFromSuperview();
_myButton.RemoveFromSuperview();
// remove reference from hooking up event handler
_button.TouchUpInside -= PushNewController;
_myButton.TouchUpInside -= MyButtonTouched;
_button = null;
_myButton = null;
}
public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated);
if(_nextController != null)
{
_nextController.CleanUpRefs();
_nextController = null;
}
}
}
MyButton不是一个直接的UIButton,因为它是继承的,这似乎有点不同。但话说回来,为什么调用RemoveFromSuperview()
会删除对它的额外引用计数,特别是当有一个类似于它的UIButton不需要删除时
(我为非常糟糕的布局道歉,stackoverflow似乎在代码段上方的项目符号布局上有问题)
更新:我向MonoTouch团队提交了一份错误报告。如果您想运行示例项目,可以从那里下载它 在这种情况下不进行垃圾收集的原因只是MonoTouch中的一个bug 即将发布的MonoTouch版本将对此进行修复。如果您赶时间,可以将/Developer/MonoTouch/usr/lib/mono/2.1/MonoTouch.dll替换为我放在这里的副本: 我会做一个备份,以防我在“正在进行的工作”库中出错