从 IntPtr 句柄获取 Xamarin.iOS NSObject(新的或缓存的) [英] Get Xamarin.iOS NSObject (new or cached) from IntPtr handle

查看:25
本文介绍了从 IntPtr 句柄获取 Xamarin.iOS NSObject(新的或缓存的)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Foundation.NSObject 的 Xamarin 文档中,生命周期部分,它说:

In Xamarin documentation for Foundation.NSObject, in Lifecycle section, it says:

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

C# NSObjects are also created on demand when you invoke a method or a property that returns an NSObject. At this point, the runtime will look into an object cache and determine whether a given Objective-C NSObject has already been surfaced to the managed world or not. If the object has been surfaced, the existing object will be returned, otherwise a constructor that takes an IntPtr as a parameter is invoked to construct the object.

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

Is there a way to do the above from my code? In other words, given an IntPtr handle, can I get a C# NSObject if it already exists or let Xamarin create a new one if it doesn't?

我想做上面的原因是我想保留一个 C# NSObjectIntPtr 句柄然后 Dispose()它.在代码的后面,我想从 IntPtr 中取回 NSObject.

The reason I want to do the above is that I want to keep the IntPtr handle of a C# NSObject and then Dispose() it. Later in the code, I want to get the NSObject back from that IntPtr.

我想做上述事情的原因是我已经阅读足够的文档博客 和 SO questions 关于 C# 垃圾收集器和 Xamarin.iOS 中的本机引用计数对象之间的交互,我决定尽快 Dispose() 一切可能的.因此,在所有方法中,每当我获得 NSObject 参数时,我都会使用 using.例如:

The reason I want to do the above is that I've read enough documentation, blogs and SO questions about the interaction between the C# garbage collector and the native refcounted objects in Xamarin.iOS that I decided to Dispose() everything as soon as possible. So in all methods, I use using whenever I get an NSObject argument. For example:

[Foundation.Action("buttonPressed:")]
public void RatingButtonTapped(UIButton button) {
    using (button) {
        Console.WriteLine("Hello world");
    }
}

因此,如果我在初始化期间保留了对 UIButton 的引用,它将在此操作运行时被释放.因此,我打算保留 IntPtr 句柄,并在以后需要时重新获取 UIButton.

So if I had kept a reference to the UIButton earlier during initialization, it will be disposed when this action is run. So instead, I plan to keep the IntPtr handle instead and re-get the UIButton when I need it later.

推荐答案

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

You can use this method to get the managed object for a handle:

ObjCRuntime.Runtime.GetNSObject (handle);

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

But have in mind that if the native object has been freed, you will crash.

如果不想崩溃,就需要保留原生句柄,等不需要的时候再释放.

If you don't want to crash, you need to retain the native handle, and then release it when you don't need it anymore.

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

If you add logic to retain+release the native handle, then you can just as well keep the managed object around, and only call Dispose when you determine you don't need the object anymore.

奇怪的是,您链接到 XY 问题,却陷入了那个确切的陷阱:您的实际问题是内存泄漏(我假设,但您没有解释),并且您正在询问尝试的解决方案(处理所有内容).

Curiously you link to the XY problem, and you're falling into that exact trap: your actual problem is that you have memory leaks (I assume, but you didn't explain), and you're asking about your attempted solution (dispose everything).

但那是问题的错误解决方案.使用此解决方案,您将陷入痛苦的世界(您已经找到了一个,如果继续保留句柄,您最终会陷入更糟糕的境地:如何解决崩溃而不是如何解决内存泄漏).

But that's the wrong solution to the problem. You will run into a world of pain with this solution (you've already found one, and if you go ahead with keeping handles around you'll end up in a much worse place: how to solve crashes instead of how to solve memory leaks).

正确的解决方法是:

  1. 诊断(和分析)以了解实际发生的情况(内存泄漏).
  2. 仅处理您知道不再需要的对象(并且 GC 无法确定不需要的对象).您希望尽可能少地处理(它使您的代码更易于维护),并且您需要先执行第 1 步才能了解这些对象.
  1. Diagnose (and profile) to understand what's really happening (with the memory leaks).
  2. Only dispose objects that you know are no longer needed (and that the GC couldn't already determine isn't needed). You want to dispose as little as possible (it makes your code easier to maintain), and you need to do step 1 first in order to know those objects.

这篇关于从 IntPtr 句柄获取 Xamarin.iOS NSObject(新的或缓存的)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆