Auf Seite 17 dieser WWDC14-Präsentation heißt es
Arbeiten mit Objective-C? Autorelease-Pools müssen noch verwaltet werden Autorelease-Pool
{/ * code * /}
Was bedeutet das? Bedeutet dies, dass autoreleasepool {}
es unnötig ist , wenn meine Codebasis keine Objective-C-Dateien enthält ?
In einer Antwort auf eine verwandte Frage gibt es ein Beispiel, wo autoreleasepool
es nützlich sein kann:
- (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);
}
}
}
}
Wenn der obige Code mit autoreleasepool
gelöscht in Swift übersetzt wird, ist Swift dann klug genug zu wissen, dass die number
Variable nach dem ersten freigegeben werden sollte }
(wie es einige andere Sprachen tun)?
memory-management
swift
Ethan
quelle
quelle
autoreleasepool
In Swift scheint es keine Dokumentation zu geben . Ich habe Ihre Frage erweitert und in den Entwicklerforen gestellt .Antworten:
Das
autoreleasepool
Muster wird in Swift verwendet, wennautorelease
Objekte zurückgegeben werden (entweder von Ihrem Objective-C-Code oder mithilfe von Cocoa-Klassen erstellt). Dasautorelease
Muster in Swift funktioniert ähnlich wie in Objective-C. Betrachten Sie zum Beispiel diese schnelle Wiedergabe Ihrer Methode (InstanziierenNSImage
/UIImage
Objekte):Wenn Sie dies in Instruments ausführen, wird ein Zuordnungsdiagramm wie das folgende angezeigt:
Wenn Sie dies jedoch ohne den Autorelease-Pool tun, werden Sie feststellen, dass die maximale Speichernutzung höher ist:
Mit dieser
autoreleasepool
Option können Sie explizit verwalten, wann Autorelease-Objekte in Swift freigegeben werden, genau wie dies in Objective-C möglich war.Hinweis: Wenn Sie mit nativen Swift-Objekten arbeiten, erhalten Sie im Allgemeinen keine Autorelease-Objekte. Aus diesem Grund wurde in der Präsentation die Einschränkung erwähnt, dass dies nur bei der "Arbeit mit Objective-C" erforderlich ist, obwohl ich mir wünschte, Apple wäre in diesem Punkt klarer. Wenn Sie jedoch mit Objective-C-Objekten (einschließlich Cocoa-Klassen) arbeiten, handelt es sich möglicherweise um Autorelease-Objekte. In diesem Fall ist diese schnelle Wiedergabe des Objective-C-
@autoreleasepool
Musters weiterhin nützlich.quelle
println
Indeinit
ausführen lassen, und es wird ziemlich einfach, genau zu überprüfen, wann Objekte freigegeben werden. Oder beobachten Sie es in Instrumenten. Bei der Beantwortung Ihrer Frage werden anscheinend Swift-Objekte von Funktionen mit +1 Anzahl beibehalten (keine Autorelease-Objekte) zurückgegeben, und der Aufrufer verwaltet den Besitz ab diesem Zeitpunkt nahtlos (z. B. wenn das zurückgegebene Objekt außerhalb des Gültigkeitsbereichs liegt). Es wird sofort freigegeben und nicht in einen Autorelease-Pool gestellt.NSImage
/UIImage
objects und manifestierte das Problem konsistenter (und ehrlich gesagt ist dies ein häufigeres Beispiel für das Problem, da die maximale Speichernutzung oft nur bei größeren Objekten problematisch ist; ein praktisches Beispiel hierfür könnte sein eine Routine zur Größenänderung einer Reihe von Bildern). Ich habe auch das Verhalten reproduziert, das Objective-C-Code aufruft, der explizit Autorelease-Objekte erstellt hat. Versteh mich nicht falsch: Ich denke, wir brauchen in Swift seltener Autorelease-Pools als in Objective-C, aber es spielt immer noch eine Rolle.pathForResource:ofType:
wiederholt NSBundle an .pathForResource:ofType:
Beispiel funktioniert nicht mehr in Xcode 6.3 / Swift 1.2. :)Wenn Sie es im entsprechenden Objective-C-Code verwenden würden, würden Sie es in Swift verwenden.
Nur wenn Objective-C dies tut. Beide arbeiten nach den Regeln für die Speicherverwaltung von Cocoa.
Natürlich weiß ARC, dass dies
number
am Ende dieser Iteration der Schleife nicht mehr möglich ist, und wenn es beibehalten wird, wird es dort freigegeben. Dies sagt Ihnen jedoch nicht, ob das Objekt automatisch freigegeben wurde, da-[NSNumber numberWithInt:]
möglicherweise eine automatisch freigegebene Instanz zurückgegeben wurde oder nicht . Sie können es auf keinen Fall wissen, da Sie keinen Zugriff auf die Quelle von haben-[NSNumber numberWithInt:]
.quelle
autoreleasepool
Konstrukt völlig unnötig ist. Wenn Ihr Swift-Code jedoch Objective-C-Objekte (einschließlich Cocoa-Objekte) verarbeitet, folgen diese Autorelease-Mustern, sodass dasautoreleasepool
Konstrukt nützlich wird.