Xamarin.iOS의 새 참조 계산 시스템

Xamarin.iOS 9.2.1은 기본적으로 모든 애플리케이션에 향상된 참조 계산 시스템을 도입했습니다. 이전 버전의 Xamarin.iOS에서 추적 및 수정하기 어려웠던 많은 메모리 문제를 제거하는 데 사용할 수 있습니다.

새 참조 계산 시스템 사용

Xamarin 9.2.1을 기준으로 새 ref 계산 시스템은 기본적으로 모든 애플리케이션에 사용하도록 설정됩니다.

기존 애플리케이션을 개발하는 경우 .csproj 파일을 검사 아래와 MtouchUseRefCounting 같이 모든 항목이 설정되도록 할 true수 있습니다.

<MtouchUseRefCounting>true</MtouchUseRefCounting>

애플리케이션으로 false 설정된 경우 새 도구를 사용하지 않습니다.

이전 버전의 Xamarin 사용

Xamarin.iOS 7.2.1 이상에서는 새로운 참조 계산 시스템의 향상된 미리 보기를 제공합니다.

클래식 API:

이 새 참조 계산 시스템을 사용하도록 설정하려면 아래와 같이 프로젝트 iOS 빌드 옵션의 고급 탭에 있는 참조 계산 확장 검사 상자 사용을 검사.

Enable the new Reference Counting System

이러한 옵션은 최신 버전의 Mac용 Visual Studio 제거되었습니다.

통합 API:

새 참조 계산 확장은 통합 API에 필요하며 기본적으로 사용하도록 설정해야 합니다. 이전 버전의 IDE에는 이 값이 자동으로 검사 않을 수 있으며 검사 직접 배치해야 할 수도 있습니다.

Important

이 기능의 이전 버전은 MonoTouch 5.2 이후로 사용되었지만 실험적 미리 보기로 sgen만 사용할 수 있었습니다. 이 새롭고 향상된 버전은 이제 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;
   }
}

참조 개수 확장이 없으면 이 코드는 수집 가능해지므로 TouchDown 충돌 cell 하므로 해당 대리자가 중단되어 현수 포인터로 변환됩니다.

참조 개수 확장은 네이티브 개체가 네이티브 코드에 의해 유지되는 경우 관리되는 개체를 활성 상태로 유지하고 해당 컬렉션을 방지합니다.

또한 새 시스템은 바인딩에 사용되는 대부분의 프라이빗 지원 필드의 필요성을 제거합니다. 이는 인스턴스를 활성 상태로 유지하는 기본 방법입니다. 관리형 링커는 새 참조 개수 확장을 사용하여 애플리케이션에서 불필요한 필드를 모두 제거할 수 있을 만큼 스마트합니다.

즉, 관리되는 각 개체 인스턴스는 이전보다 적은 메모리를 사용합니다. 또한 일부 백업 필드에 런타임에 더 이상 Objective-C 필요하지 않은 참조가 있는 관련 문제를 해결하여 일부 메모리를 회수하기가 어렵습니다.