Last active
January 18, 2017 06:31
-
-
Save externvoid/665082a88ce5a7896f3d7db6f97702fa to your computer and use it in GitHub Desktop.
解読したい、Swiftコード、unSafe族が良く判らん!<- ✳️コメント有り✳️
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Foundation | |
| enum Vehicle { | |
| case Car(windows: Int, wheels: Int) | |
| case Ship(windows: Int, funnels: Int, anchors: Int) | |
| case Plane(windows: Int, wheels: Int, wings: Int, engines: Int) | |
| } | |
| var aPlane: Vehicle = .Plane(windows: 1, wheels: 9, wings: 8, engines: 4) | |
| var voidPtr: UnsafePointer<Vehicle> = unsafeBitCast(&aPlane, | |
| UnsafePointer<Vehicle>.self) | |
| // Int8 takes 1 byte (8 bits) memory space. | |
| //let bytePointer = withUnsafePointer(&aPlane) { UnsafePointer<Int8>($0) } | |
| let bytePointer = withUnsafePointer(&aPlane) { ptr in | |
| unsafeBitCast(ptr, UnsafePointer<Int8>.self) | |
| //UnsafePointer<Int8>(ptr) | |
| } | |
| let bytePointer1 = withUnsafePointer(&aPlane) { $0 } | |
| print(bytePointer.dynamicType) // UnsafePointer<Int8> | |
| print(bytePointer1.dynamicType) //UnsafePointer<Vehicle> | |
| var offsetString: String = "" | |
| var contentString: String = "" | |
| for offset in 0..<sizeof(Vehicle) { | |
| offsetString += String(format: "%02d ", offset) | |
| contentString += String(format: "%02d ", bytePointer[offset]) | |
| } | |
| print("offset:\t" + offsetString) | |
| print("content:\t" + contentString) | |
| // With unsafeBitCast | |
| //extension Vehicle { | |
| // var windows: Int { | |
| // let casted = unsafeBitCast(aPlane, (Int, Int, Int, Int, Int8).self) | |
| // return casted.0 | |
| // } | |
| //} | |
| // With withUnsafePointer | |
| extension Vehicle { | |
| var windows: Int { | |
| var mutableSelf = self | |
| let ptr = withUnsafePointer(&mutableSelf) { | |
| UnsafePointer<(Int, Int, Int, Int, Int8)>($0) | |
| } | |
| print(ptr) | |
| print(ptr.memory) | |
| print(ptr.memory.0) | |
| //return ptr[0].0 | |
| return ptr.memory.0 | |
| } | |
| } | |
| print(aPlane.windows) |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
✳️unsafeBitCast関数
func unsafeBitCast<T, U>(x: T, _: U.Type) -> U
インスタンスをビット列と見なして型解釈し直して、インスタンスを返す。
インスタンスがアドレスであっても良い。その場合はアドレスが返る。
✳️withUnsafePointer関数⁉️ ⁉️ アドレスの型変換ができる。void* -> char*とか⁉️
Useful for calling Objective-C APIs、ポインタを引数に取るAPIを呼ぶのに便利、例えばVoid型のポインタとか。withUnsafeMutablePointers型も仲間
必ず、アドレスを引数にとる
✳️UnsafePointer型(構造体)、アドレスを表す⁉️
memoryメソッドで値を返す。(アドレスにある値)
UnsafeMutablePointer型も仲間
⭕️withUnsafePointer
Invokes body with an UnsafePointer to arg and returns the result.
argへのポインタを受取るclosure(body)を呼び出しresultを返す。▶️ って事は、ポインタを受け取るって事だよねぇ。戻り値に関しては、なんでも良いのか?アドレスでもインスタンスでも?▶️ その通り
enum Vehicle {
case Car(windows: Int, wheels: Int)
case Ship(windows: Int, funnels: Int, anchors: Int)
case Plane(windows: Int, wheels: Int, wings: Int, engines: Int)
}
var aPlane: Vehicle = .Plane(windows: 1, wheels: 9, wings: 8, engines: 4)
//print(aPlane[windows])
let bytePointer1 = withUnsafePointer(&aPlane) { $0.memory }
print(bytePointer1) //Plane(1, 9, 8, 4, 2)
let bytePointer2 = withUnsafePointer(&aPlane) { $0 }
print(bytePointer2) //UnsafePointer