2017-01-20 10 views
1

Ich machte einige Tests mit Zeigern in Swift und wollte überprüfen, dass die Objekte, auf die ich Zeiger nahm, nicht beibehalten wurden.Warum behält Swift "Managed.fromOpaque.takeUnletainedValue()" den Wert?

func test1(){ 
    let str = aaa(); 
    print(CFGetRetainCount(str)) 
    let ptr1 = Unmanaged.passUnretained(str).toOpaque() 
    print(CFGetRetainCount(str)) 
    let str2 = Unmanaged<aaa>.fromOpaque(ptr1).takeUnretainedValue(); 
    print(CFGetRetainCount(str2)) 
} 

Das Ergebnis ist 2,2,3. So wurde "passUnready" nicht beibehalten, sondern "takeUnretainedValue" tat.

Die Änderung zu "takeRetainedValue" behebt das Problem und verursacht den erwarteten Absturz. Ausgabe 2,2,2.

func test1(){ 
    let str = aaa(); 
    print(CFGetRetainCount(str)) 
    let ptr1 = Unmanaged.passUnretained(str).toOpaque() 
    print(CFGetRetainCount(str)) 
    let str2 = Unmanaged<aaa>.fromOpaque(ptr1).takeRetainedValue(); 
    print(CFGetRetainCount(str2)) 
} 

Also, um zu schließen, behält "TakeRetainedValue" nicht den Wert.

Update: Ich habe diese Frage bearbeitet, um einige zuvor verwirrende Anweisungen zu entfernen und es zu einer grundlegenden Programmierfrage zurückgegeben.

+0

Ja. Ich habe das erste Problem herausgefunden. "passUnready" behält nicht bei, aber "takeUnretypedValue" tut es. Dies sind jedoch keine verwandten Paare, aber passUnready (+0) wird von passRetained (+1) entgegengesetzt. Denken Sie, ich sollte dieses Problem einfach löschen, da es keine mögliche Begründung oder kein Coding-Problem mehr gibt? – user1122069

+0

Ich bin froh, dass es für Sie Sinn macht. Nicht sarkastisch sein. Es ist wichtig zu verstehen, was die Begriffe bedeuten, um sie richtig zu verwenden und Code überprüfen zu können. – user1122069

Antwort

0

Tatsächlich stellt sich heraus, dass "takeUnletainedValue" den Wert nicht behält, sondern durch die Zuweisung selbst, nachdem der Wert zurückgegeben wurde.

Ich habe getestet und festgestellt, dass, solange "passRetained" mit "takeRetained" und "passUnreadyed" mit "takeUnreadyed" verwendet wird, die Variable nicht leckt, und es ist nur +1 aufgrund der neuen Variablen hinzugefügt.

func test1() -> UnsafeMutableRawPointer { 
    let str = aaa(); 
    print(CFGetRetainCount(str)) 
    let ptr1 = Unmanaged.passRetained(str).toOpaque() 
    print(CFGetRetainCount(str)) 
    let str2 = Unmanaged<aaa>.fromOpaque(ptr1).takeRetainedValue(); 
    print(CFGetRetainCount(str2)) 
    print(str2); 
    print("111"); 
    print(str.b) 
    return ptr1; 
} 

let ptr4 = test1(); 
let str4 = Unmanaged<aaa>.fromOpaque(ptr4).takeUnretainedValue(); 
print(CFGetRetainCount(str4)) 
print(str4.b); 

Hier ist ein Test zeigt, dass takeUnretainedValue nicht den Verweiszähler nicht erhöht (die Zuordnung entfernt, sondern rief die Funktion sowieso).

func test1() { 
    let str = aaa(); 
    print(CFGetRetainCount(str)) 
    let ptr1 = Unmanaged.passUnretained(str).toOpaque() 
    print(CFGetRetainCount(str)) 
    Unmanaged<aaa>.fromOpaque(ptr1).takeUnretainedValue(); 
    print(CFGetRetainCount(str)) 
    //print(str2); 
    print("111"); 
    print(str.b) 
} 

Ähnliche Tests zeigen, dass "takeRetainedValue" den Retain-Zähler dekrementiert. Es bezieht sich auf die "Extra-Retain" von passRetained und gibt den Wert so zurück, wie er war, als er gestartet wurde. Es wird auch +1 zugewiesen, wenn es zugewiesen wird.

+0

Die Frage ist und wurde betitelt "Warum Swift" Managed.fromOpaque.takeUnpenedValue() "den Wert behalten?". Tatsache ist, dass takeUnletainedValue nicht beibehalten wird und daher die Verwirrung besteht. – user1122069

Verwandte Themen