【问题标题】:Why would MonoTouch not garbage collect my custom UIButton unless I call button.RemoveFromSuperview()?除非我调用 button.RemoveFromSuperview(),否则为什么 MonoTouch 不会垃圾收集我的自定义 UIButton?
【发布时间】:2011-07-28 07:19:31
【问题描述】:

似乎有一些东西引用了我的自定义按钮MyButton(继承自UIButton),导致它不会被垃圾收集,除非我从超级视图中删除它。这反过来又会导致它所在的视图控制器也没有被最终确定和收集。

在我的示例中,我有我的自定义按钮,但我在视图控制器上也有一个标准的UIButton,不需要从超级视图中删除即可被收集。有什么不同?长得跟我很像。

查看此代码。例如,删除了不相关的行。关于样本的一些注意事项:

-MyButton 很空。只是一个构造函数,没有其他任何东西被覆盖。

-想象MyViewControllerUINavigationController

-LoadView() 只是创建按钮,为每个按钮绑定一个事件并将其添加到视图中

-触摸_button 会将另一个MyViewController 推送到导航控制器

-在ViewDidAppear() 中从导航控制器弹出视图控制器时,我正在做一些参考清理

-在CleanUpRefs() 中,您会看到我必须从superview 中删除_myButton,以便对所有对象进行垃圾回收。 _button,另一方面不需要删除。

-我希望在从导航控制器弹出但注释掉 _myButton.RemoveFromSuperview() 时会收集整个 MyViewController,包括所有子视图。

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 似乎在代码 sn-ps 上方布置项目符号时遇到问题)

更新:我向 MonoTouch 团队提交了一份错误报告。如果你想运行它,你可以从那里下载示例项目。 Bug 92.

【问题讨论】:

    标签: xamarin.ios


    【解决方案1】:

    在那种情况下不进行垃圾收集的原因只是 MonoTouch 中的一个错误。

    即将发布的 MonoTouch 版本将包含对此的修复。如果你赶时间,你可以将你的 /Developer/MonoTouch/usr/lib/mono/2.1/monotouch.dll 替换为我放在这里的副本:

    http://tirania.org/tmp/monotouch.dll

    我会做一个备份,以防我在我的工作库中做错了什么。

    【讨论】:

      猜你喜欢
      • 2020-03-06
      • 2017-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多