2016-01-13 38 views
0

在Xamarin文档Foundation.NSObject,在Lifecycle section,它说:也是按需创建获取Xamarin.iOS NSObject的从IntPtr的(新的或缓存)处理

C#NSObjects当你调用一个方法或属性,返回一个NSObject。此时,运行时将查看对象缓存并确定给定的Objective-C NSObject是否已经出现在受管理的世界中。如果对象已经出现,则返回现有对象,否则调用将IntPtr作为参数的构造函数来构造该对象。

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

我想这样做的原因是我想保留一个C#NSObjectIntPtr句柄,然后Dispose()它。在代码后面,我想从IntPtr得到NSObject

The reason I want to do the above是我读够了documentationblogs和SO que小号tiØns关于C#垃圾收集和Xamarin.iOS本地引用计数的对象,我决定Dispose()一切之间的相互作用,只要可能。所以在所有方法中,只要我得到NSObject参数,我就使用using。例如:

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

所以,如果我一直保持到初始化期间UIButton早参考,运行这个动作时将布置。相反,我计划保留IntPtr句柄,并在稍后需要时重新获取UIButton

回答

4

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

ObjCRuntime.Runtime.GetNSObject (handle); 

但有一点,如果本地对象已被释放,你会崩溃。

如果你不想崩溃,你需要保留本地句柄,然后在你不再需要时释放它。

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

奇怪的是你链接到XY的问题,你陷入了确切的陷阱:你的实际问题是你有内存泄漏(我假设,但你没有解释),你问关于您的尝试解决方案(处置所有内容)。

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

正确的解决方法是:

  1. 诊断(和配置文件),以了解真正的情况(与内存泄漏)。
  2. 只处置对象,你知道不再需要(并且GC不能确定是不需要的)。您希望尽可能少地使用(它使您的代码更容易维护),并且您需要先执行第1步以便了解这些对象。
+0

你是对的,但我真正的*实际* **实际**问题是,我试图找到一种一致的方式来管理内存*之前*我甚至开始项目。我刚刚完成了一个Xamarin.Android应用程序,因为我不了解C#GC如何与Java GC交互(我最终放弃并偶尔调用GC.Collect()),导致内存泄漏。所以我想从这个新项目开始时就要格外小心,现在做一些愚蠢的事情来学习,而不是在项目结束的时候太迟地学习它们。 – imgx64

+0

是的,谢谢,我已经编辑了答案。 –