Новая система подсчета ссылок в Xamarin.iOS

Xamarin.iOS 9.2.1 по умолчанию представила расширенную систему подсчета ссылок для всех приложений. Его можно использовать для устранения многих проблем с памятью, которые были трудно отслеживать и устранять в более ранних версиях Xamarin.iOS.

Включение новой системы подсчета ссылок

По состоянию на Xamarin 9.2.1 новая система подсчета ссылок включена для всех приложений по умолчанию.

При разработке существующего приложения можно проверка CSPROJ-файл, чтобы убедиться, что все вхождения заданы MtouchUseRefCountingtrueследующим образом:

<MtouchUseRefCounting>true</MtouchUseRefCounting>

Если оно установлено false для приложения, оно не будет использовать новые средства.

Использование старых версий Xamarin

Xamarin.iOS 7.2.1 и более поздних версий предоставляет расширенную предварительную версию новой системы подсчета ссылок.

Классический API:

Чтобы включить эту новую систему подсчета ссылок, проверка поле "Использовать расширение подсчета ссылок", проверка box на вкладке "Дополнительно" для параметров сборки iOS проекта, как показано ниже:

Enable the new Reference Counting System

Обратите внимание, что эти параметры были удалены в более новых версиях Visual Studio для Mac.

Унифицированный API:

Новое расширение подсчета ссылок требуется для единого API и должно быть включено по умолчанию. Старые версии интегрированной среды разработки могут не иметь этого значения, проверка автоматически, и вам может потребоваться разместить проверка самостоятельно.

Внимание

Более ранняя версия этой функции была доступна с MonoTouch 5.2, но была доступна только для гена в качестве экспериментальной предварительной версии. Эта новая расширенная версия теперь доступна для сборщика мусора Boehm .

Исторически существовали два типа объектов, управляемых Xamarin.iOS: те, которые были просто оболочкой вокруг собственного объекта (одноранговые объекты) и те, которые расширили или включили новые функциональные возможности (производные объекты) — как правило, сохраняя дополнительное состояние в памяти. Ранее можно было расширить одноранговый объект с состоянием (например, добавив обработчик событий C#), но мы позволяем объекту перейти к отмене ссылок, а затем собрать. Это может привести к сбою позже (например, если Objective-C среда выполнения возвращается в управляемый объект).

Новая система автоматически обновляет одноранговые объекты на объекты, управляемые средой выполнения при хранении дополнительных сведений.

Это решает различные аварии, которые произошли в таких ситуациях, как этот:

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 делегат, который преобразуется в дальнего указателя.

Расширение счетчика ссылок гарантирует, что управляемый объект остается в живых и предотвращает его коллекцию, если собственный объект сохраняется машинным кодом.

Новая система также удаляет необходимость в большинстве частных полей резервной копии, используемых в привязках, что является подходом по умолчанию для поддержания активности экземпляра. Управляемый компоновщик достаточно умный, чтобы удалить все ненужные поля из приложений с помощью нового расширения счетчика ссылок.

Это означает, что каждый экземпляр управляемых объектов потребляет меньше памяти, чем раньше. Она также решает связанную проблему, когда некоторые поля резервного копирования будут содержать ссылки, которые больше не нужны Objective-C средой выполнения, что затрудняет восстановление некоторой памяти.