Hmm ...Swift - deinit heißt nicht
Ich habe ein kleines Problem mit einem unerwarteten Verhalten in Swif4 Speicherverwaltung. In der Tat bin ich dabei einen deinit Anruf
Grundsätzlich ist das Layout der andernfalls Codeteil ist wie folgt:
class A {
init() {
print("A init \(unsafeBitCast(self, to: UnsafeMutableRawPointer.self)) called")
}
deinit {
print("A deinit \(unsafeBitCast(self, to: UnsafeMutableRawPointer.self)) called")
}
func c() {
print("A c called")
}
}
class B {
var a : A
init() {
a = A() <-- required because a is not optional
}
func c() {
a = A()
a.c()
}
}
var b = B()
b.c()
b.c()
b.c()
ich simulierte dies im Spielplatz und der (erwartete) Ausdruck war (w/o Kommentare):
A init 0x000060c00000c540 called <-- initial init
A init 0x000060c00000c800 called <-- first b.c()
A deinit 0x000060c00000c540 called
A c called
A init 0x000060400000c4c0 called <-- second b.c()
A deinit 0x000060c00000c800 called
A c called
A init 0x000060400000c4a0 called <-- third b.c()
A deinit 0x000060400000c4c0 called
A c called
Leider verhalten sich meine realen Klassen nicht so. Tatsächlich verhalten sie sich wie folgt:
A init 0x000060c00000c540 called <-- initial init
A init 0x000060c00000c800 called <-- first b.c()
A deinit 0x000060c00000c540 called
A c called
A init 0x000060400000c4c0 called <-- second b.c()
A deinit 0x000060c00000c800 called <-- missing!
A c called
A init 0x000060400000c4a0 called <-- third b.c()
A deinit 0x000060400000c4c0 called <-- missing!
A c called
Also, im Grunde erscheint nur das erste Deinit, keine nachfolgenden. Ich fürchte, Speicherlecks (obwohl Instruments mir keinen Hinweis gibt).
Jede Idee, welche Operationen könnten dieses Verhalten hervorrufen? Ich habe keine Zirkelverweise, zumindest sehe ich sie nicht.
Könnte ein Verweis auf B irgendwo sein ... B unterstützt URLSessionDelegate-Protokoll .... EDIT: Es ist höchstwahrscheinlich dadurch verursacht. Wenn ich die URLSessionDelegate-Unterstützung entferne, ist alles in Ordnung. – decades
Spielplatz oder REPL (einschließlich LLDB-Konsole) ist kein guter Ort, um ARC-bezogene Verhaltensweisen zu überprüfen. Erstellen Sie ein Befehlszeilentool oder ein anderes aktuelles App-Projekt, um Ihren Code zu testen. – OOPer
Rechts. Ich habe nur den Spielplatz benutzt, um (mich) das richtige erwartete Verhalten zu demonstrieren. Siehe meine Antwort unten. – decades