注意:我创建了一个简单的项目 - 您可以看到故事板之间
UIButton和CustomButton故事板中的切换类型如何改变GC行为.
我正试图让我的脑袋缠绕着MonoTouch垃圾收集器.
该问题类似于MT 4.0中修复的问题,但是使用了继承类型.
为了说明它,请考虑两个视图控制器,父级和子级.
子视图包含一个UIButton可以随时写入控制台的视图.
Controller的Dispose方法会引发异常,因此很难错过.
这里是子视图控制器:
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
sayHiButton.TouchUpInside += (sender, e) =>
SayHi();
}
}
void SayHi()
{
Console.WriteLine("Hi");
}
protected override void Dispose (bool disposing)
{
throw new Exception("Hey! I've just been collected.");
base.Dispose (disposing);
}
Run Code Online (Sandbox Code Playgroud)
父视图控制器只显示子控制器并设置一个计时器来关闭它并运行GC:
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
var child = (ChildViewController)Storyboard.InstantiateViewController("ChildViewController");
NSTimer.CreateScheduledTimer(2, () => {
DismissViewController(false, null);
GC.Collect();
}); …Run Code Online (Sandbox Code Playgroud) 在Xamarin文档Foundation.NSObject,在生命周期节,它说:
当调用返回NSObject的方法或属性时,也会按需创建C#NSObject。此时,运行时将调查对象缓存,并确定给定的Objective-C NSObject是否已浮出水面。如果对象已浮出水面,则将返回现有对象,否则将调用以IntPtr作为参数的构造函数来构造该对象。
有没有办法从我的代码中做到上述几点?换句话说,给定一个IntPtr句柄,我可以得到一个NSObject已经存在的C#,或者让Xamarin创建一个不存在的C#吗?
我要执行上述操作的原因是,我想保留IntPtrC#的句柄,NSObject然后再保留Dispose()它。在代码的NSObject后面,我想从中得到支持IntPtr。
究其原因我想上面做的是,我读过足够的文档,博客和SO 阙小号TI Ø NS关于C#垃圾收集和Xamarin.iOS本地引用计数对象之间的互动,我决定Dispose() 一切,只要可能。因此,在所有方法中,using只要有NSObject参数就使用。例如:
[Foundation.Action("buttonPressed:")]
public void RatingButtonTapped(UIButton button) {
using (button) {
Console.WriteLine("Hello world");
}
}
Run Code Online (Sandbox Code Playgroud)
因此,如果我UIButton在初始化期间保留了对较早版本的引用,则在运行此操作时将对其进行处理。因此,我计划保留该IntPtr句柄,并UIButton在以后需要时重新获取它。