Pergunta

Como eu a entendo, tudo o que é criado com um alloc, novo, ou cópia precisa ser lançado manualmente.Por exemplo:

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

A minha pergunta, porém, não seria tão válido?:

int main(void) {
    NSAutoreleasePool *pool;
    pool = [[NSAutoreleasePool alloc] init];
    NSString *string;
    string = [[[NSString alloc] init] autorelease];
    /* use the string */
    [pool drain];
}
Foi útil?

Solução

Sim, o segundo código de snippit é perfeitamente válida.

De cada vez -autorelease é enviada a um objeto, ele é adicionado para o interior-a maioria pool de autorelease.Quando a piscina é drenado, ele simplesmente envia -release para todos os objetos na piscina.

Autorelease piscinas são simplesmente uma conveniência que permite você adiar o envio de libertação até que "mais tarde".Que "mais tarde" pode acontecer em vários lugares, mas o mais comum no Cacau aplicações GUI é no final da execução actual ciclo.

Outras dicas

NSAutoreleasePool:drenagem vs.lançamento

Desde que a função de drain e release parecem estar causando confusão, pode ser a pena esclarecer aqui (apesar de isto é coberto no a documentação...).

Estritamente falando, a imagem grande perspectiva drain é não equivalente a release:

Em uma referência contados de meio ambiente, drain executar as mesmas operações como release, assim que os dois são, nesse sentido equivalente.De salientar, isso significa que você não vazamento de uma piscina, se você usar drain em vez de release.

Em uma lata de lixo-coletado ambiente, release é um não-op.Assim, ele não tem efeito. drain, por outro lado, contém uma sugestão para o coletor, que deveria recolher, se necessário".Assim, em uma lata de lixo-coletado ambiente, usando drain ajuda o equilíbrio do sistema de coleta de varreduras.

Como já salientado, o segundo trecho de código está correto.

Gostaria de sugerir uma forma mais sucinta maneira de usar o pool de autorelease que funciona em todos os ambientes (ref contagem, GC, ARC) e também evita a drenagem/release confusão:

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

No exemplo acima, por favor, note que o @autoreleasepool bloco.Isto está documentado aqui.

Não, você está errado.A documentação indica claramente que, em condições não-GC, de dreno é equivalente a liberação, ou seja, o NSAutoreleasePool vai não ser vazado.

O que eu li da Apple:"No final do pool de autorelease bloco, objetos que recebeu um autorelease mensagem dentro do bloco são enviados uma mensagem de libertação, um objeto recebe uma mensagem de libertação por cada hora em que foi enviada uma autorelease mensagem dentro do bloco."

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

enviar autorelease em vez de liberação para um objeto aumenta o tempo de vida do objeto, pelo menos até a piscina é drenada (pode ser mais, se o objeto é então mantida).Um objeto pode ser colocado no mesmo grupo, várias vezes, caso em que recebe uma mensagem de libertação, para cada vez que ele foi colocado na piscina.

Sim e não.Você iria acabar liberando a memória de seqüência de caracteres, mas "vazamento" o NSAutoreleasePool objeto na memória usando de drenagem em vez de libertar se você executou isso sob um lixo coletado (memória não gerenciada) meio ambiente.Essa "fuga" simplesmente faz com que a instância do NSAutoreleasePool "inacessível" como qualquer outro objeto com a forte ponteiros em GC, e o objeto seria limpo até a próxima vez que a GC é executado, o que poderia muito bem ser diretamente após a chamada para -drain:

drenagem

Em uma lata de lixo coletado ambiente, dispara a recolha de dados se a memória alocada desde a última coleção é maior do que o atual limite;caso contrário comporta-se como uma libertação....Em uma lata de lixo-coletado ambiente, este método, em última análise, chamadas de objc_collect_if_needed.

Caso contrário, é semelhante à forma como -release comporta-se em não-GC, sim.Como outros têm afirmado, -release é um não-op em GC, então a única maneira de certificar-se de que a piscina funciona corretamente no GC é através de -drain, e -drain sob o GC não funciona exatamente como uma -release sob não-GC, e, sem dúvida, comunica a sua funcionalidade de forma mais clara também.

Gostaria de salientar que a sua declaração de "nada chamado com o novo, alocação ou init" não deve incluir "init" (mas deve incluir "copiar"), porque "init" não alocar memória, ele apenas define o objeto (construtor de moda).Se você recebeu uma alocação seria objeto e sua função apenas chamado de init como tal, você não iria liberá-lo:

- (void)func:(NSObject*)allocd_but_not_init
{
    [allocd_but_not_init init];
}

Que não consome mais memória do que você já começou com (supondo que o init não instanciar objetos, mas você não está responsável por estes de qualquer maneira).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top