swift version =>: swift 5.0
struct StructValue {
let a: Int8 = 4
let b: Int16 = 6
let c: Int32 = 8
}
var structValue = StructValue()
let structValuePointer = withUnsafePointer(to: &structValue) { UnsafeMutableRawPointer(mutating: $0) }
structValuePointer.advanced(by: 2).assumingMemoryBound(to: Int16.self).initialize(to: 99)
// structValue.b = 99
typealias TupleValue = (Int8, Int32, String)
struct StructValue {
var a: Int8 = 4
var b: Int32 = 5
var c: String = "SwiftTuple"
}
let structValue = StructValue()
let tupleValue = unsafeBitCast(structValue, to: TupleValue.self)
print(tupleValue.1)
// print 5 (structValue.b)
// if TupleValue = (Int8, Int8, String) => MemoryLayout of TupleValue != MemoryLayout of StructValue
class A {
var a = 666
}
let a1 = A()
unowned let unowned_a = a1
let a2 = a1
weak var weak_a = a1
weak var weak_a2 = a1
unowned let unowned_a2 = a1
let a3 = a2
let a4 = a2
weak var weak_a3 = a1
unowned let unowned_a3 = a1
print(UnownedRefCount(a1))
print(WeakRefCount(a1)!)
print(StrongRefCount(a2))
// test with debug
protocol SwiftProtocol {
func foo()
func foo2()
}
struct StructValue: SwiftProtocol {
func foo() {
print("foo")
}
func foo2() {
print("foo2")
}
}
var Protocol: SwiftProtocol = StructValue()
let protocol_pointer = withUnsafePointer(to: &Protocol) { UnsafeMutableRawPointer(mutating: $0) }
let witness_table_pointer_value = protocol_pointer.advanced(by: 32).assumingMemoryBound(to: UInt.self).pointee
let witness_table_pointer = UnsafeMutablePointer<UnsafeMutableRawPointer>.init(bitPattern: witness_table_pointer_value)
typealias Foo2Method = @convention(thin) ()->Void
let witness_foo2_pointer = unsafeBitCast(witness_table_pointer!.advanced(by: 2).pointee, to: Foo2Method.self)
witness_foo2_pointer()
// print foo2
enum EnumValue {
case a
case b(String)
case c(Int32)
case d
case f(Int64)
case e
}
var enumC = EnumValue.c(8)
let enumCPointer = withUnsafePointer(to: &enumC) { UnsafeMutableRawPointer(mutating: $0) }
enumCPointer.advanced(by: 16).assumingMemoryBound(to: Int8.self).initialize(to: 0x02)
// enumC = EnumValue.f(8)
var bool = true
let boolPointer = bool.valuePointer
boolPointer.initialize(to: -10)
// bool = false
var optional: Int16? // 0x00 0x00 0x01
var optionalPointer = optional.valuePointer
optionalPointer.assumingMemoryBound(to: Int16.self).initialize(to: 99) // 0x63 0x00 0x01
optionalPointer.advanced(by: MemoryLayout<Int16>.size).assumingMemoryBound(to: UInt8.self).initialize(to: 0x00) // 0x63 0x00 0x00
// optional = 99
var string = "TannerJin"
let stringPointer = string.valuePointer
stringPointer.assumingMemoryBound(to: Int8.self).initialize(to: 0x40) // 0x40 => "@"
// string = "@anner Jin"
var character = Character("π")
let characterPointer = character.valuePointer.assumingMemoryBound(to: UInt8.self)
characterPointer.initialize(to: 0xf0) // f0 9f 9a 80 => "π" unicode(utf-8)
characterPointer.advanced(by: 1).initialize(to: 0x9f)
characterPointer.advanced(by: 2).initialize(to: 0x9a)
characterPointer.advanced(by: 3).initialize(to: 0x80)
// character = "π"
let array = ["Apple", "Swift"]
let arrayPointer = array.valuePointer
arrayPointer.initialize(to: "Tanner")
// array = ["Tanner", "Swift"]
array.countPointer.initialize(to: 3)
// array.count = 3
let set: Set<String> = ["Apple", "iOS", "Swift"]
set.valuesPointer.initialize(to: "Tanner")
// set = ["Tanner", "Swift", "iOS"] || ["Tanner", "Swift", "Apple"] || ...
set.countPointer.initialize(to: 2)
// set.count = 2
let dictionary = ["Swift": 5.0, "iOS": 2019]
let dicCountPointer = dictionary.countPointer
let dicKeysPointer = dictionary.keysPointer
let dicValuesPointer = dictionary.valuesPointer