共用方式為


Xamarin.iOS 中的新參考計數系統

Xamarin.iOS 9.2.1 預設會將增強的參考計數系統引入所有應用程式。 它可以用來消除許多在舊版 Xamarin.iOS 中難以追蹤和修正的記憶體問題。

啟用新的參考計數系統

從 Xamarin 9.2.1 開始,新的 ref counting 系統預設會啟用至 所有 應用程式。

如果您正在開發現有的應用程式,您可以檢查 .csproj 檔案,以確保 所有出現的 MtouchUseRefCounting 項目都設定為 true,如下所示:

<MtouchUseRefCounting>true</MtouchUseRefCounting>

如果應用程式設定為 false ,則不會使用新的工具。

使用舊版 Xamarin

Xamarin.iOS 7.2.1 和更新版本具有我們新參考計數系統的增強預覽功能。

傳統 API:

若要啟用這個新的參考計數系統,請檢查專案 iOS 組建選項的 [進階] 索引卷標中找到的 [使用參考計數延伸模組] 複選框,如下所示:

Enable the new Reference Counting System

請注意,這些選項已在較新版本的Visual Studio for Mac 中移除。

整合 API:

整合 API 需要新的參考計數延伸模組,且預設應啟用。 舊版的 IDE 可能不會自動核取此值,您可能必須自行進行檢查。

重要

自 MonoTouch 5.2 以來,此功能的較舊版本已四處可見,但僅適用於 sgen 作為實驗性預覽。 這個新的增強版本現在也可供 Boehm 垃圾收集行程使用。

從歷史上看,Xamarin.iOS 管理的物件有兩種:這些物件只是原生物件(對等物件)的包裝函式,以及擴充或併入新功能的物件(衍生物件),通常是藉由保留額外的記憶體內部狀態。 先前,我們可以使用狀態來增強對等物件(例如,新增 C# 事件處理程式),但我們會讓物件不受推斷,然後加以收集。 這可能會導致稍後發生損毀(例如, Objective-C 如果運行時間回呼至Managed物件)。

新的系統會在運行時間儲存任何額外資訊時,自動將對等對象升級為由運行時間管理的物件。

這可解決在這類情況下發生的各種當機:

class MyTableSource : UITableViewSource {
   public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) {
        var cell = tableView.DequeueReusableCell ("myId");
        if (cell != null)
                return cell;

        cell = new UITableViewCell (UITableViewCellStyle.Default, "myId");
        var txt = new UITextField ();
        txt.TouchDown += delegate { Console.WriteLine ("...."); };
        cell.ContentView.AddSubview (txt);
        return cell;
   }
}

如果沒有參考計數延伸模組,此程式代碼就會損毀,因為 cell 會變成可收集的,因此其 TouchDown 委派會轉譯成懸空的指標。

參考計數延伸模組可確保 Managed 物件保持運作,並防止其集合,前提是原生物件會由原生程式代碼保留。

新的系統也會移除系結中使用的大部分私人支援字段的需求,這是讓實例保持運作的預設方法。 受控連結器足夠聰明,可使用新的參考計數延伸模組,從應用程式移除所有 不必要的 字段。

這表示每個受控物件實例耗用的記憶體都比之前少。 它也會解決一個相關問題,其中某些備份欄位會保存運行時間不再需要的 Objective-C 參考,因此很難回收某些記憶體。