web-dev-qa-db-ja.com

Swiftで値型またはカスタム構造体のメモリアドレスを取得するにはどうすればよいですか?

私はSwift 値の型をコピーする の方法をより深く理解しようとしています:

コードに表示される動作は、常にコピーが行われたかのようになります。ただし、Swiftは、本当に必要な場合にのみ、舞台裏で実際のコピーを実行します。

理解を深めるために、値型のメモリアドレスを取得したいと思います。 unsafeAddressOf()を試しましたが、 これは構造体では機能せず、Swiftの標準ライブラリ型を参照型にキャストするようです (たとえば、文字列はNSStringにキャストされます)。

IntのインスタンスやSwiftのカスタム構造体など、値タイプのメモリアドレスを取得するにはどうすればよいですか?

11
GingerBreadMane

マーティンRの回答によると

addressOf()は、構造体変数では使用できません。文字列は構造体ですが、オブジェクトが必要な関数に渡されると、自動的にNSStringにブリッジされます。

Nschumの答えによると、次のようなstruct、組み込みタイプ、またはオブジェクト参照の(スタック)アドレスを取得できます。

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"

私が見つけた1つのことは、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""
22
ilovecomputer

Swift 2.0:

これを使うことができますunsafeAddressOf(someObject)

またはSwift 3.0:

withUnsafePointer(to: someObejct) { print("\($0)") }を使用します

9
broccoli

それを行うための「推奨される」方法があるかどうかはわかりませんが、1つの方法は、次のようにwithUnsafePointer(_:_:)を使用することです。

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

これは0x00007ffff52a011c8私のマシン。

5
Chris Vig