2016-01-13 40 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

是的,謝謝,我已經編輯了答案。 –