不在Xamarin的UIViewController上调用dealloc

时间:2015-08-31 06:42:23

标签: ios objective-c memory-leaks xamarin xamarin.ios

我有一个UIViewController写在一个绑定到我的Xamarin应用程序的本机库中。控制器有如下方法:

+ (instancetype)newInstance
{
    return [SharedData.sharedInstance.mainStoryboard instantiateViewControllerWithIdentifier:@"worksheetController"];
}

此方法绑定到我的Xamarin应用程序,如下所示:

// @interface WorksheetTableViewController : UIViewController
[BaseType(typeof(UIViewController))]
interface WorksheetTableViewController
{
    // +(instancetype)newInstance;
    [Static]
    [Export("newInstance")]
    WorksheetTableViewController NewInstance();
}

现在,我在ViewDidLoad的UIViewController子类中的Xamarin应用程序中调用方法如下:

this.worksheetController = WorksheetTableViewController.NewInstance();

worksheetController中的任何其他地方均未使用UIViewController。如果处理此UIViewController(通过弹出导航堆栈),则不会调用dealloc WorksheetTableViewController方法。

但是,如果我将ViewDidLoad中的代码更改为如下:

this.worksheetController = (WorksheetTableViewController)SharedData.SharedInstance.MainStoryboard.InstantiateViewController("worksheetController");

当放置UIViewController时,会调用dealloc方法。

对我而言,本机代码中newInstance方法与Xamarin中直接调用InstantiateViewController似乎没有任何区别。然而在前一种情况下dealloc没有被调用,而后者的一切都很好。

有人可以解释为什么两种情况下的内存管理不同吗?

1 个答案:

答案 0 :(得分:2)

这是因为ARC将隐式保留原始newInstance方法[1]的返回值,而Xamarin.iOS不会隐式检测到它。

您有两种选择:

  1. 将原生方法重命名为不以newcopy开头的内容(还有一些其他前缀,请参阅[1]以获取完整列表) ,以便ARC不会自动保留返回值。

  2. [return: Release ()]添加到a​​pi定义中(这告诉Xamarin.iOS ARC正在做什么,Xamarin.iOS将添加额外的release调用):

    [Static]
    [Export("newInstance")]
    [return: Release ()]
    WorksheetTableViewController NewInstance();
    
  3. [1] http://clang.llvm.org/docs/AutomaticReferenceCounting.html#method-families