Pergunta

Eu tenho lido sobre o autoreleasepool, mas há um ponto que não está claro para mim. Eu tenho algumas funcionalidades usando threads que exigiam gerenciamento de memória separado usando o AutorEleasEPool.

No exemplo seguinte está correto

-(void) doSomething {

   NSAutorelease *pool = [[NSAutorelasepool alloc] init];

   NSString *myString = @"Hello";

   [pool release];
}

Isso está correto?

-(void) doSomething {

   NSAutorelease *pool = [[NSAutorelasepool alloc] init];

   NSString *myString = [[NSString alloc] initWithString:@"Hello"];

   [pool release];
}

ou isto?

-(void) doSomething {

   NSAutorelease *pool = [[NSAutorelasepool alloc] init];

   NSString *myString = [[NSString alloc] initWithString:@"Hello"];

   [myString release];
   [pool release];
}

Minha pergunta é de propriedade dos objetos criados no escopo do pool de autorlease, precisa ser relatado especificamente ou o cuidado de quando o autorelasepool é lançado?

Teo

Foi útil?

Solução

O AutoRelease Pool lida com os objetos autorizados. Se você possui um objeto (por meio de aloces ou copiar ou reter), deve liberá -lo. Portanto, seu segundo exemplo não está correto. Como você alocou a string, você a possui e deve liberá -la.

Um pool de autorlease é criado para o encadeamento principal. (Você pode olhar para a função principal, se quiser). Cada encadeamento precisa de seu próprio pool autorlease para gerenciar objetos autorizados. É por isso que, se você criar outro thread, deve criar um pool autorlease para esse thread. Mesmo se você não criar objeto autorizado no thread, você deve criar isso, pois a biblioteca chama nesse thread pode criar objetos autorizados. Mesmo se você tiver certeza de que nenhuma chamada de biblioteca está fazendo objetos autorizados, também deve criá -los, pois essa é a melhor prática, especialmente se você estiver trabalhando no Big Project, que é desenvolvido e mantido por várias pessoas.

Outras dicas

Você só precisa criar seu próprio pool de autorlease quando está criando um monte de objetos autorizados que deseja coleta imediatamente. No entanto, você está correto, pois não deseja fazer referência a nenhum objetivo "autorleçado" que crie depois de lançar o pool. Os objetos autorizados (que você não mantém) são destruídos quando a piscina é drenada.

Como nenhum dos objetos do seu exemplo é autorizado, a criação de seu próprio pool de autorlease é essencialmente um não-operatório.

Nenhum de seus exemplos precisa de um pool de autorlease. Os pools autorlease apenas cuidam de objetos autorizados:

NSArray *foo = [NSArray array];
NSObject *bar = [[[NSObject alloc] init] autorelease];

Sua primeira string é inicializada usando uma string literal e, portanto, é provavelmente especial em relação ao gerenciamento de memória (talvez alguém saiba mais). Sua segunda corda vaza, a piscina não faz diferença. Sua terceira sequência é lançada corretamente, novamente o pool não faz diferença.

É aqui que você precisaria de uma piscina:

- (void) someMethodThatRunsOnAThread {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSString *foo = [@"foo" uppercaseString];
    [pool drain];
}

Aqui o foo String vazaria se a piscina não estivesse lá. Observe que estou ligando drain ao invés de release Na piscina-no iOS, não há diferença, mas em ambientes coletados de lixo os dois diferem, por isso é provavelmente melhor adquirir o hábito de chamar o certo.

Observe também que você pode precisar de um pool, mesmo que você não elimine os objetos, pode haver muitas operações de memória em algum lugar no código que você está chamando no seu método.

Acho que isso deve ser algo assim:

-(void) doSomething {

   NSAutorelease *pool = [[NSAutorelasepool alloc] init];


   NSString *myString = [[[NSString alloc] initWithString:@"Hello"] autorelease];

   // or create string like this (automatically autoreleased)
   NSString *myString = [NSString stringWithString:@"Hello"];

   [pool release];
}

Você deve enviar uma mensagem de autorlease, para objetos dentro do piscinas automáticas. Eles serão lançados quando a mensagem de lançamento for enviada para o pool.

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