À la page 17 de cette présentation de la WWDC14 , il est dit
Travailler avec Objective-C? Vous devez encore gérer les pools de
libération automatique autoreleasepool {/ * code * /}
Qu'est-ce que ça veut dire? Cela signifie-t-il que si ma base de code ne contient aucun fichier Objective-C, autoreleasepool {}
est-ce inutile?
Dans une réponse à une question connexe , il y a un exemple où cela autoreleasepool
peut être utile:
- (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);
}
}
}
}
Si le code ci-dessus est traduit en Swift avec autoreleasepool
drop, Swift sera-t-il assez intelligent pour savoir que la number
variable doit être publiée après la première }
(comme le font d'autres langues)?
memory-management
swift
Ethan
la source
la source
autoreleasepool
Swift. J'ai développé votre question et l' ai posée dans les forums de développement .Réponses:
Le
autoreleasepool
modèle est utilisé dans Swift lors du retour desautorelease
objets (créés par votre code Objective-C ou à l'aide de classes Cocoa). Leautorelease
modèle dans Swift fonctionne un peu comme il le fait dans Objective-C. Par exemple, considérez ce rendu Swift de votre méthode (instanciationNSImage
/UIImage
objets):Si vous exécutez ceci dans Instruments, vous verrez un graphique d'allocations comme celui-ci:
Mais si vous le faites sans le pool de libération automatique, vous verrez que l'utilisation maximale de la mémoire est plus élevée:
Le
autoreleasepool
vous permet de gérer explicitement le moment où les objets de libération automatique sont désalloués dans Swift, tout comme vous avez pu le faire dans Objective-C.Remarque: lorsque vous traitez avec des objets natifs Swift, vous ne recevrez généralement pas d'objets à libération automatique. C'est pourquoi la présentation a mentionné la mise en garde sur le fait de n'avoir besoin de cela que lorsque "travailler avec Objective-C", bien que j'aurais aimé qu'Apple soit plus clair sur ce point. Mais si vous avez affaire à des objets Objective-C (y compris des classes Cocoa), ils peuvent être des objets à libération automatique, auquel cas ce rendu Swift du
@autoreleasepool
modèle Objective-C est toujours utile.la source
println
indeinit
, et il devient assez facile de vérifier précisément quand les objets sont désalloués. Ou observez-le dans Instruments. En réponse à votre question, il semble que les objets Swift soient renvoyés à partir de fonctions avec un compte de conservation +1 (pas d'objets de libération automatique), et l'appelant gérera de manière transparente la propriété à partir de ce point (par exemple, si et quand l'objet retourné tombe hors de portée, il est immédiatement désalloué et non placé dans un autoreleasepool).NSImage
/UIImage
objets et manifesté le problème de manière plus cohérente (et, franchement, c'est un exemple plus courant du problème, car l'utilisation maximale de la mémoire n'est souvent problématique que lorsqu'il s'agit d'objets plus grands; un exemple pratique de cela pourrait être une routine redimensionnant un tas d'images). J'ai également reproduit le comportement appelant le code Objective-C qui créait explicitement des objets de libération automatique. Ne vous méprenez pas: je pense que nous avons besoin de pools de libération automatique dans Swift moins souvent que dans Objective-C, mais cela a toujours un rôle à jouer.pathForResource:ofType:
plusieurs reprises.pathForResource:ofType:
exemple ne fonctionne plus dans Xcode 6.3 / Swift 1.2. :)Si vous l'utilisiez dans le code Objective-C équivalent, vous l'utiliseriez dans Swift.
Seulement si Objective-C le fait. Les deux fonctionnent selon les règles de gestion de la mémoire Cocoa.
Bien sûr, ARC sait que cela
number
sort de la portée à la fin de cette itération de la boucle, et s'il la retient, il la libère là-bas. Cependant, cela ne vous indique pas si l'objet a été automatiquement publié, car-[NSNumber numberWithInt:]
il peut avoir renvoyé ou non une instance de publication automatique. Vous ne pouvez pas le savoir, car vous n’avez pas accès à la source de-[NSNumber numberWithInt:]
.la source
autoreleasepool
construction est totalement inutile. Mais si votre code Swift gère des objets Objective-C (y compris des objets Cocoa), ceux-ci suivent des modèles de libération automatique, et donc laautoreleasepool
construction devient utile.