不在 Xamarin 的 UIViewController 上调用 dealloc
Not calling dealloc on UIViewController in Xamarin
我有一个 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();
}
现在,在我的 Xamarin 应用程序中,在 ViewDidLoad 的 UIViewController
子类中,我按如下方式调用该方法:
this.worksheetController = WorksheetTableViewController.NewInstance();
worksheetController
未在 UIViewController
的其他任何地方使用。当这个 UIViewController
被处理(通过弹出导航堆栈)时,WorksheetTableViewController
的 dealloc
方法不会被调用。
但是,如果我将 ViewDidLoad 中的代码更改为如下:
this.worksheetController = (WorksheetTableViewController)SharedData.SharedInstance.MainStoryboard.InstantiateViewController("worksheetController");
当 UIViewController
被释放时,会调用 dealloc 方法。
对我来说,本地代码中的 newInstance
方法和直接在 Xamarin 中调用 InstantiateViewController
似乎没有任何区别。然而在前一种情况下 dealloc
没有被调用,而在后一种情况下一切都很好。
谁能解释一下为什么这两种情况下内存管理不同?
这是因为 ARC 将隐式保留本机 newInstance
方法 [1] 中的 return 值,而 Xamarin.iOS 不会隐式检测到该值。
您有两个选择:
将本机方法重命名为不以 new
或 copy
开头的名称(还有一些其他前缀,请参阅 [1] 了解完整信息列表),这样 ARC 就不会自动保留 return 值。
将[return: Release ()]
添加到api定义中(这告诉Xamarin.iOSARC在做什么,Xamarin.iOS将添加一个额外的release
调用):
[Static]
[Export("newInstance")]
[return: Release ()]
WorksheetTableViewController NewInstance();
[1] http://clang.llvm.org/docs/AutomaticReferenceCounting.html#method-families
我有一个 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();
}
现在,在我的 Xamarin 应用程序中,在 ViewDidLoad 的 UIViewController
子类中,我按如下方式调用该方法:
this.worksheetController = WorksheetTableViewController.NewInstance();
worksheetController
未在 UIViewController
的其他任何地方使用。当这个 UIViewController
被处理(通过弹出导航堆栈)时,WorksheetTableViewController
的 dealloc
方法不会被调用。
但是,如果我将 ViewDidLoad 中的代码更改为如下:
this.worksheetController = (WorksheetTableViewController)SharedData.SharedInstance.MainStoryboard.InstantiateViewController("worksheetController");
当 UIViewController
被释放时,会调用 dealloc 方法。
对我来说,本地代码中的 newInstance
方法和直接在 Xamarin 中调用 InstantiateViewController
似乎没有任何区别。然而在前一种情况下 dealloc
没有被调用,而在后一种情况下一切都很好。
谁能解释一下为什么这两种情况下内存管理不同?
这是因为 ARC 将隐式保留本机 newInstance
方法 [1] 中的 return 值,而 Xamarin.iOS 不会隐式检测到该值。
您有两个选择:
将本机方法重命名为不以
new
或copy
开头的名称(还有一些其他前缀,请参阅 [1] 了解完整信息列表),这样 ARC 就不会自动保留 return 值。将
[return: Release ()]
添加到api定义中(这告诉Xamarin.iOSARC在做什么,Xamarin.iOS将添加一个额外的release
调用):[Static] [Export("newInstance")] [return: Release ()] WorksheetTableViewController NewInstance();
[1] http://clang.llvm.org/docs/AutomaticReferenceCounting.html#method-families