从IntPtr句柄获取Xamarin.iOS NSObject(new或cached)

时间:2016-01-13 08:48:17

标签: ios xamarin xamarin.ios

Foundation.NSObject的Xamarin文档中,在Lifecycle section中,它说:

  

当您调用返回NSObject的方法或属性时,也会根据需要创建C#NSObject。此时,运行时将查看对象缓存并确定给定的Objective-C NSObject是否已经浮出水面到托管世界。如果对象已浮出,则将返回现有对象,否则将调用以IntPtr作为参数的构造函数来构造对象。

有没有办法从我的代码中执行上述操作?换句话说,给定一个IntPtr句柄,如果它已经存在,我可以得到一个C#NSObject,或者如果不存在,可以让Xamarin创建一个新的吗?

我想要执行上述操作的原因是我希望保留C#IntPtr然后NSObject的{​​{1}}句柄。在代码的后面部分,我希望从Dispose()返回NSObject

The reason I want to do the above我已经阅读了足够的documentationblogs和SO que s ti o ns关于C#垃圾收集器和Xamarin.iOS中的本机refcounted对象,我决定尽快IntPtr 一切。因此,在所有方法中,每当我得到Dispose()参数时,我都会使用using。例如:

NSObject

因此,如果我在初始化期间保留了对[Foundation.Action("buttonPressed:")] public void RatingButtonTapped(UIButton button) { using (button) { Console.WriteLine("Hello world"); } } 的引用,那么在运行此操作时将会将其处理掉。相反,我打算保留UIButton句柄,并在以后需要时重新获取IntPtr

1 个答案:

答案 0 :(得分:5)

您可以使用此方法获取句柄的托管对象:

ObjCRuntime.Runtime.GetNSObject (handle);

但请记住,如果本机对象已被释放,您将崩溃。

如果您不想崩溃,则需要保留原生句柄,然后在您不再需要时将其释放。

如果您添加逻辑以保留+释放本机句柄,那么您也可以保留托管对象,并且只有在您确定不再需要该对象时才调用Dispose。

奇怪的是,您链接到XY问题,并且您正陷入这个确切的陷阱:您的实际问题是您有内存泄漏(我猜,但你没有解释),并且您正在询问您的尝试解决方案(处置所有内容)。

但这是解决问题的错误方法。使用这个解决方案你会遇到一个痛苦的世界(你已经找到了一个,如果你继续保持你周围的把柄,最终会处于一个更糟糕的地方:如何解决崩溃而不是如何解决崩溃解决内存泄漏问题。)

正确的解决方案是:

  1. 诊断(和配置文件)以了解实际发生的事情(内存泄漏)。
  2. 仅处理您不再需要的对象(并且GC无法确定是否需要)。您希望尽可能少地处置(它使您的代码更易于维护),并且您需要先执行步骤1才能知道这些对象。