Novo sistema de contagem de referências no Xamarin.iOS

O Xamarin.iOS 9.2.1 introduziu o sistema de contagem de referência aprimorado para todos os aplicativos por padrão. Ele pode ser usado para eliminar muitos problemas de memória que eram difíceis de rastrear e corrigir em versões anteriores do Xamarin.iOS.

Habilitando o novo sistema de contagem de referências

A partir do Xamarin 9.2.1, o novo sistema de contagem de ref está habilitado para todos os aplicativos por padrão.

Se você estiver desenvolvendo um aplicativo existente, poderá marcar o arquivo .csproj para garantir que todas as ocorrências de MtouchUseRefCounting sejam definidas truecomo , como abaixo:

<MtouchUseRefCounting>true</MtouchUseRefCounting>

Se ele estiver definido como false seu aplicativo não usará as novas ferramentas.

Usando versões mais antigas do Xamarin

O Xamarin.iOS 7.2.1 e superior apresenta uma versão prévia aprimorada do nosso novo sistema de contagem de referências.

API clássica:

Para habilitar esse novo Sistema de Contagem de Referências, marcar caixa de seleção Usar a extensão de contagem de referência encontrada na guia Avançado das opções de Build do iOS do projeto, conforme mostrado abaixo:

Habilitar o novo sistema de contagem de referência

Observe que essas opções foram removidas em versões mais recentes do Visual Studio para Mac.

API unificada:

A nova extensão de contagem de referência é necessária para a API Unificada e deve ser habilitada por padrão. Versões mais antigas do seu IDE podem não ter esse valor verificado automaticamente e talvez você precise colocar uma marcar por ele mesmo.

Importante

Uma versão anterior desse recurso existe desde o MonoTouch 5.2, mas só estava disponível para sgen como uma versão prévia experimental. Essa nova versão aprimorada agora também está disponível para o coletor de lixo boehm .

Historicamente, houve dois tipos de objetos gerenciados pelo Xamarin.iOS: aqueles que eram apenas um wrapper em torno de um objeto nativo (objetos pares) e aqueles que estenderam ou incorporaram novas funcionalidades (objetos derivados) – geralmente mantendo o estado extra na memória. Anteriormente, era possível aumentar um objeto par com o estado (por exemplo, adicionando um manipulador de eventos C#), mas permitimos que o objeto não fosse referenciado e, em seguida, coletado. Isso pode causar uma falha posteriormente (por exemplo, se o Objective-C runtime chamar de volta para o objeto gerenciado).

O novo sistema atualiza automaticamente objetos pares para objetos gerenciados pelo runtime quando armazenam informações extras.

Isso resolve várias falhas que ocorreram em situações como esta:

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;
   }
}

Sem a extensão de contagem de referência, esse código falharia porque cell se torna colecionável e, portanto, seu TouchDown delegado, que se traduzirá em um ponteiro pendente.

A extensão de contagem de referência garante que o objeto gerenciado permaneça ativo e impede sua coleção, desde que o objeto nativo seja retido pelo código nativo.

O novo sistema também remove a necessidade da maioria dos campos de suporte privados usados em associações , que é a abordagem padrão para manter a instância ativa. O vinculador gerenciado é inteligente o suficiente para remover todos esses campos desnecessários de aplicativos usando a nova extensão de contagem de referência.

Isso significa que cada instância de objeto gerenciado consome menos memória do que antes. Ele também resolve um problema relacionado em que alguns campos de suporte manteriam referências que não eram mais necessárias para o Objective-C runtime, dificultando a recuperação de memória.