it-swarm-pt.tech

Como funciona o pool de autorelease do NSAutoreleasePool?

Pelo que entendi, qualquer coisa criada com um alloc , new ou copy precisa ser liberada manualmente. Por exemplo:

int main(void) {
    NSString *string;
    string = [[NSString alloc] init];
    /* use the string */
    [string release];
}

Minha pergunta, no entanto, não seria válida ?:

int main(void) {
    NSAutoreleasePool *pool;
    pool = [[NSAutoreleasePool alloc] init];
    NSString *string;
    string = [[[NSString alloc] init] autorelease];
    /* use the string */
    [pool drain];
}
94
James Sumners

Sim, seu segundo trecho de código é perfeitamente válido.

Toda vez que uma autorização é enviada para um objeto, ele é adicionado ao pool de autorelease mais interno. Quando o pool é drenado, ele simplesmente envia -release a todos os objetos no pool.

Os pools de liberação automática são simplesmente uma conveniência que permite adiar o envio da release até "mais tarde". Esse "mais tarde" pode acontecer em vários lugares, mas o mais comum nos aplicativos Cocoa GUI é no final do ciclo de ciclo de execução atual.

65
kperryua

NSAutoreleasePool: dreno vs. liberação

Uma vez que a função drain e release parece estar causando confusão, pode valer a pena esclarecer aqui (embora isto seja coberto em a documentação ...).

Estritamente falando, do ponto de vista da grande figura, drain é não equivalente a release:

Em um ambiente de contagem de referência, drain realiza as mesmas operações que release, então os dois são nesse sentido equivalentes. Para enfatizar, isso significa que você não vaza um pool se você usar drain em vez de release.

Em um ambiente de coleta de lixo, release é um não operacional. Assim, não tem efeito. drain, por outro lado, contém uma sugestão para o coletor que deve "coletar se necessário". Assim, em um ambiente de coleta de lixo, o uso de drain ajuda a varredura da coleção de balanceamento do sistema.

37
mmalc

Como já foi mencionado, seu segundo trecho de código está correto.

Eu gostaria de sugerir uma maneira mais sucinta de usar o pool de autorelease que funciona em todos os ambientes (ref count, GC, ARC) e também evita a confusão de dreno/liberação:

int main(void) {
  @autoreleasepool {
    NSString *string;
    string = [[[NSString alloc] init] autorelease];
    /* use the string */
  }
}

No exemplo acima, observe o bloco @autoreleasepool. Isso está documentado aqui .

17
Neovibrant

Não, você está errado. A documentação declara claramente que em não-GC, -drain é equivalente a -release, significando que o NSAutoreleasePool irá não ser vazado.

7
kperryua

Eu encontrei este link deu a melhor explicação sobre quando e como usar NSAutoReleasePool: AutoReleasePool

1
Wayne Lo

o envio de autorelease em vez de liberação para um objeto estende a vida útil desse objeto pelo menos até que o próprio conjunto seja drenado (pode ser mais longo se o objeto for subsequentemente retido). Um objeto pode ser colocado no mesmo pool várias vezes, caso em que recebe uma mensagem de liberação para cada vez que foi colocado no pool.

0
Hardik Mamtora

sim, seu código é perfeito, se você estiver usando coleta de lixo, seria suficiente apenas definir a seqüência de caracteres para nil quando você é feito com ele. A coleta de lixo não é boa para o desempenho do seu aplicativo, então eu não recomendaria usá-lo: P

0
Antwan van Houdt

O que eu li da Apple: "No final do bloco de pool de autorelease, objetos que receberam uma mensagem de liberação automática dentro do bloco recebem uma mensagem de liberação - um objeto recebe uma mensagem de liberação para cada vez que foi enviado um autorelease mensagem dentro do bloco ".

https://developer.Apple.com/library/mac/documentation/cocoa/conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html

0
Gagan_iOS