Quando o disparo automático realmente causar uma liberação em Cocoa Touch?
-
21-08-2019 - |
Pergunta
Eu entendo que você precisa ter cuidado com autorelease
no iOS. Eu tenho um método que está retornando um objeto que ele alloc
s que é necessário pelo chamador, então nesta situação - como eu o entendo -. Eu preciso enviar autorelease
para o objeto no receptor antes de retornar
Isso é bom, mas uma vez que o controle retorna para o telefone (ou seja, depois do meu clique do botão foi processado), parece que a piscina disparo automático é lançado. Eu suspeito que esta é a forma como é suposto ser, mas eu estou querendo saber qual é a melhor prática para esta situação.
I têm recorrido a enviar uma mensagem retain
do chamador para que o objeto não é liberado e depois explicitamente liberá-lo em dealloc
.
Esta é a melhor abordagem?
Solução
A piscina disparo automático é normalmente liberado após cada iteração do loop prazo. Grosso modo, cada aplicação Cocoa e Cocoa Touch é estruturado como este:
Get the next message out of the queue
Create an autorelease pool
Dispatch the message (this is where your application does its work)
Drain the autorelease pool
O que você descreve é ??o comportamento esperado. Se você quiser manter um objeto em torno de mais tempo do que isso, você vai precisar para retê-lo explicitamente.
Outras dicas
Usando autorelease
é uma maneira de dizer, "Object, eu não quero mais você, mas eu vou passá-lo para alguém que pode querer que você, por isso não desaparecem ainda." Assim, o objeto vai ficar por tempo suficiente para que você possa devolvê-lo a partir de um método ou dá-la a outro objeto. Quando algum código quer manter o objeto ao redor, deve reivindica a posse por retain
ing-lo.
as diretrizes de gerenciamento de memória para tudo que você precisa saber para usar autorelease
corretamente.
Aqui está um examle fornecidas em o documento de gerenciamento de memória da Apple :
– (id)findMatchingObject:(id)anObject
{
id match = nil;
while (match == nil) {
NSAutoreleasePool *subPool = [[NSAutoreleasePool alloc] init];
/* Do a search that creates a lot of temporary objects. */
match = [self expensiveSearchForObject:anObject];
if (match != nil) {
[match retain]; /* Keep match around. */
}
[subPool release];
}
return [match autorelease]; /* Let match go and return it. */
}
Sim, essa é a melhor abordagem. Disparo automático é realmente destinados apenas para interações no código que você sabe. Uma vez que você está armazenando um objeto, você deverá saber que o objeto que contém uma referência não vai morrer / sair do escopo até você também está feito com o objeto, ou você precisa para manter o objeto.
Ela só é garantido que os objetos autoreleased será lançado após o final do seu método. Afinal, o método que chamou o seu método poderia ter criado a sua própria piscina e liberá-lo logo após o seu método.