2017-11-18 3 views
0

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.

+0

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

+3

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

+0

Rechts. Ich habe nur den Spielplatz benutzt, um (mich) das richtige erwartete Verhalten zu demonstrieren. Siehe meine Antwort unten. – decades

Antwort

0

OK, behoben. Das Problem war, dass meine "A" -Klasse als Referenz von einer URLSession (als Delegierter) gehalten wurde. Da diese Sitzung nicht ordnungsgemäß beendet wurde, wurde das A-Objekt nicht deinitialisiert.