2016-05-23 5 views
7

Ich versuche, ein tieferes Verständnis davon, wie Swift copies value types zu gewinnen:Wie kann ich die Speicheradresse eines Werttyps oder einer benutzerdefinierten Struktur in Swift abrufen?

Das Verhalten, das Sie in Ihrem Code sehen immer sein wird, als ob eine Kopie stattfand. Swift führt jedoch nur dann eine Kopie hinter den Kulissen aus, wenn dies unbedingt erforderlich ist.

Um mein Verständnis zu verbessern, möchte ich die Speicheradresse eines Werttyps erhalten. Ich probierte unsafeAddressOf(), aber this doesn't work with structs and it seems to cast Swift's standard library types to reference types (z. B. Zeichenfolge wird in NSString umgewandelt).

Wie kann ich die Speicheradresse eines Werttyps wie eine Instanz von Int oder eine benutzerdefinierte Struktur in Swift abrufen?

Antwort

12

Laut Martin R‘s Antwort

AddressOf() kann nicht mit struct Variablen verwendet werden. String ist eine Struktur, wird jedoch automatisch an NSString überbrückt, wenn sie an eine Funktion übergeben wird, die ein Objekt erwartet.

Nach nschum Antwort, können Sie den (Stack) Adresse eines struct erhalten, build-in-Typ oder Objektverweis wie folgt aus:

import UIKit 


func address(o: UnsafePointer<Void>) -> Int { 
    return unsafeBitCast(o, Int.self) 
} 

func addressHeap<T: AnyObject>(o: T) -> Int { 
    return unsafeBitCast(o, Int.self) 
} 


struct myStruct { 
    var a: Int 
} 

class myClas { 

} 
//struct 
var struct1 = myStruct(a: 5) 
var struct2 = struct1 
print(NSString(format: "%p", address(&struct1))) // -> "0x10f1fd430\n" 
print(NSString(format: "%p", address(&struct2))) // -> "0x10f1fd438\n" 

//String 
var s = "A String" 
var aa = s 
print(NSString(format: "%p", address(&s))) // -> "0x10f43a430\n" 
print(NSString(format: "%p", address(&aa))) // -> "0x10f43a448\n" 

//Class 
var class1 = myClas() 
var class2 = class1 
print(NSString(format: "%p", addressHeap(class1))) // -> 0x7fd5c8700970 
print(NSString(format: "%p", addressHeap(class2))) // -> 0x7fd5c8700970 

unsafeAddressOf(class1) //"UnsafePointer(0x7FD95AE272E0)" 
unsafeAddressOf(class2) //"UnsafePointer(0x7FD95AE272E0)" 

//Int 
var num1 = 55 
var num2 = num1 
print(NSString(format: "%p", address(&num1))) // -> "0x10f1fd480\n" 
print(NSString(format: "%p", address(&num2))) // -> "0x10f1fd488\n" 

Eine Sache, die ich gefunden, wenn myStruct

struct myStruct { 

} 

var struct1 = myStruct() 
var struct2 = struct1 
print(NSString(format: "%p", address(&struct1))) // -> ""0xa000000000070252\n"" 
print(NSString(format: "%p", address(&struct2))) // -> ""0xa000000000070252\n"" 
+0

So beweist dies, dass Swift nicht copy-on-write Optimierung gebaut für individuelle Structs, nur für ein paar nicht implementiert in Arten und Klassen. Interessant. –

+0

@karansatia Klassen sind Referenztypen und werden bei der Zuweisung nicht kopiert. Wenn Sie einem anderen Objekt eine Klasseninstanz zuweisen, zeigen sie auf dasselbe Objekt. Daher ist es normal, dass wir im obigen Beispiel für beide Klassen die gleiche Adresse haben. Es hat nichts mit dem Copy-on-Write zu tun. Dies gilt unabhängig davon, ob es sich um integrierte oder benutzerdefinierte Klassen handelt. Sie müssen NSCopying implementieren, um Ihre Klasse klonbar zu machen, und sie folgendermaßen zuweisen: b = a.copy() as? MyClass eher als b = a –

3

Ich bin mir nicht sicher, ob ein „empfehlenswert“ Art und Weise gibt es, das zu tun, aber eine Methode ist withUnsafePointer(_:_:) zu verwenden, wie folgt aus:

var s: String = "foo" 
withUnsafePointer(&s) { NSLog("\($0)") } 

Diese gedruckte 0x00007ffff52a011c8 auf meiner Maschine.

6

Swift 2.0:

keinen Wert hat, wird die Adresse gleich sein behalten

können Sie diese verwenden unsafeAddressOf(someObject)

oder in Swift 3.0:

Verwendung withUnsafePointer(to: someObejct) { print("\($0)") }

Verwandte Themen