Na página 17 desta apresentação WWDC14 , diz
Trabalhando com Objective-C? Ainda preciso gerenciar pools de
liberação automática autoreleasepool {/ * code * /}
O que isso significa? Isso significa que, se minha base de código não tiver nenhum arquivo Objective-C, autoreleasepool {}
é desnecessário?
Em uma resposta a uma pergunta relacionada , há um exemplo em que autoreleasepool
pode ser útil:
- (void)useALoadOfNumbers {
for (int j = 0; j < 10000; ++j) {
@autoreleasepool {
for (int i = 0; i < 10000; ++i) {
NSNumber *number = [NSNumber numberWithInt:(i+j)];
NSLog(@"number = %p", number);
}
}
}
}
Se o código acima for traduzido para o Swift com autoreleasepool
eliminado, o Swift será inteligente o suficiente para saber que a number
variável deve ser lançada após o primeiro }
(como fazem algumas outras linguagens)?
memory-management
swift
Ethan
fonte
fonte
autoreleasepool
no Swift. I expandiu sua pergunta e pediu-lo nos fóruns dev .Respostas:
O
autoreleasepool
padrão é usado em Swift ao retornarautorelease
objetos (criados por seu código Objective-C ou usando classes Cocoa). Oautorelease
padrão em Swift funciona da mesma forma que em Objective-C. Por exemplo, considere esta versão em Swift do seu método (instanciarNSImage
/UIImage
objetos):Se você executar isso em instrumentos, verá um gráfico de alocações como o seguinte:
Mas se você fizer isso sem o pool de liberação automática, verá que o pico de uso de memória é maior:
O
autoreleasepool
permite que você gerencie explicitamente quando os objetos de liberação automática são desalocados no Swift, assim como você fazia em Objective-C.Nota: Ao lidar com objetos nativos Swift, você geralmente não receberá objetos de liberação automática. É por isso que a apresentação mencionou a ressalva sobre a necessidade disso apenas ao "trabalhar com Objective-C", embora eu gostaria que a Apple fosse mais clara neste ponto. Mas se você estiver lidando com objetos Objective-C (incluindo classes Cocoa), eles podem ser objetos de liberação automática, caso em que esta versão do Swift do
@autoreleasepool
padrão Objective-C ainda é útil.fonte
println
nodeinit
, e torna-se bastante fácil de verificar precisamente quando os objetos são desalocados. Ou observe em Instrumentos. Em resposta à sua pergunta, parece que os objetos Swift são retornados de funções com contagem de retenção +1 (não objetos de liberação automática), e o chamador irá gerenciar perfeitamente a propriedade a partir desse ponto (por exemplo, se e quando o objeto retornado sair do escopo, ele é imediatamente desalocado, não colocado em um pool de liberação automática).NSImage
/UIImage
objects e manifestei o problema de forma mais consistente (e, francamente, este é um exemplo mais comum do problema, já que o pico de uso de memória muitas vezes só é problemático ao lidar com objetos maiores; um exemplo prático disso pode ser uma rotina de redimensionamento de um monte de imagens). Também reproduzi o comportamento chamando o código Objective-C que criava explicitamente objetos de autorelease. Não me interpretem mal: acho que precisamos de pools de liberação automática em Swift com menos frequência do que em Objective-C, mas ainda tem um papel a cumprir.pathForResource:ofType:
repetidamente.pathForResource:ofType:
exemplo não funciona mais no Xcode 6.3 / Swift 1.2. :)Se você o usasse no código Objective-C equivalente, você o usaria no Swift.
Somente se Objective-C o fizer. Ambos operam de acordo com as regras de gerenciamento de memória Cocoa.
É claro que o ARC sabe que
number
sai do escopo no final daquela iteração do loop e, se o reteve, o liberará lá. No entanto, isso não informa se o objeto foi liberado automaticamente, porque-[NSNumber numberWithInt:]
pode ou não ter retornado uma instância liberada automaticamente. Não há como saber, porque você não tem acesso à fonte de-[NSNumber numberWithInt:]
.fonte
autoreleasepool
construção é totalmente desnecessária. Mas se seu código Swift está lidando com objetos Objective-C (incluindo objetos Cocoa), eles seguem padrões de autorelease e, portanto, aautoreleasepool
construção se torna útil.