1、内存访问冲突会在两个访问满足以下条件时发生:
- //无内存访问冲突
- func plus(_ num: inout Int) -> Int {
- num + 1
- }
- var number = 1
- number = plus(&number)
-
- //有内存访问冲突
- var step = 1
- func increment(_ num: inout Int) {
- num += step //error
- }
- increment(&step)
-
- //解决内存访问冲突
- var copyOfStep = step
- increment(©OfStep)
- step = copyOfStep
2、如果下面的条件可以满足 ,就说明重叠访问结构体的属性是安全的
1、Swift中也有专门的指针类型,这些都被定性为“Unsafe”(不安全的),常见的有以下4中类型
- var age = 10
-
- func test1(_ ptr: UnsafeMutablePointer<Int>) {
- ptr.pointee = 20
- print("test1", ptr.pointee)
- }
-
- func test2(_ ptr: UnsafePointer<Int>) {
- print("test2", ptr.pointee);
- }
-
- func test4(_ ptr: UnsafeMutableRawPointer) {
- ptr.storeBytes(of: 30, as: Int.self)
- }
-
- func test5(_ ptr: UnsafeRawPointer) {
- print("test5", ptr.load(as: Int.self))
- }
- //OC -> BOOL *
- //Swift -> UnsafeMutablePointer<ObjCBool>
-
- var arr = NSArray(objects: 11, 22, 33, 44)
- arr.enumerateObjects { (element, idx, stop) in
- print(idx, element)
- if idx == 2 {
- stop.pointee = true
- }
- }
- var age = 10
-
- var ptr1 = withUnsafeMutablePointer(to: &age) {
- $0
- }
-
- var ptr2 = withUnsafePointer(to: &age) {
- $0
- }
-
- ptr1.pointee = 22
- print(ptr2.pointee) // 22
- print(age) // 22
-
- var ptr3 = withUnsafeMutablePointer(to: &age) {
- UnsafeMutableRawPointer($0)
- }
-
- var ptr4 = withUnsafePointer(to: &age) {
- UnsafeRawPointer($0)
- }
-
- ptr3.storeBytes(of: 33, as: Int.self)
- print(ptr4.load(as: Int.self)) // 33
- print(age) // 33
- class Person {
- var age: Int
-
- init(age: Int) {
- self.age = age
- }
- }
-
- var person = Person(age: 21)
-
- var ptr1 = withUnsafePointer(to: &person) {
- UnsafeRawPointer($0)
- }
- var personObjAddress = ptr1.load(as: UInt.self)
- var ptr2 = UnsafeMutableRawPointer(bitPattern: personObjAddress)
-
- //下面这种方式和上面的实现效果相同
- //var ptr = unsafeBitCast(person, to: UnsafeRawPointer.self)
通过指针我们可以很容易的获取内存中变量的地址值,方便窥探底层做的事情。
- var ptr = malloc(16)
-
- ptr?.storeBytes(of: 10, as: Int.self)
- ptr?.storeBytes(of: 20, toByteOffset: 8, as: Int.self)
-
- print(ptr?.load(as: Int.self)) // 10
- print(ptr?.load(fromByteOffset: 8, as: Int.self)) // 20
-
- free(ptr)
- var ptr = UnsafeMutableRawPointer.allocate(byteCount: 16, alignment: 1)
-
- ptr.storeBytes(of: 11, as: Int.self)
- ptr.advanced(by: 8).storeBytes(of: 22, as: Int.self)
-
- print(ptr.load(as: Int.self)) // 11
- print(ptr.advanced(by: 8).load(as: Int.self)) // 22
-
- ptr.deallocate()
- var ptr = UnsafeMutablePointer<Int>.allocate(capacity: 2)
- ptr.initialize(to: 10)
- ptr.successor().initialize(to: 20)
-
- print(ptr.pointee)
- print((ptr + 1).pointee)
-
- print(ptr.pointee)
- print(ptr.successor().pointee)
-
- print(ptr[0])
- print(ptr[1])
-
- ptr.deinitialize(count: 2)
- ptr.deallocate()
测试内存的释放:
- class Person {
- var age: Int
- var name: String
-
- init(age: Int, name: String) {
- self.age = age
- self.name = name
- }
-
- deinit {
- print(name, "deinit")
- }
- }
-
- var ptr = UnsafeMutablePointer<Person>.allocate(capacity: 3)
- ptr.initialize(to: Person(age: 20, name: "Jack"))
- (ptr + 1).initialize(to: Person(age: 21, name: "Rose"))
- (ptr + 2).initialize(to: Person(age: 22, name: "Kate"))
-
- ptr.deinitialize(count: 3)
- ptr.deallocate()
- var ptr = UnsafeMutableRawPointer.allocate(byteCount: 16, alignment: 1)
-
- ptr.assumingMemoryBound(to: Int.self).pointee = 11
- (ptr + 8).assumingMemoryBound(to: Double.self).pointee = 22.0
-
- var ptr2 = unsafeBitCast(ptr, to: UnsafeMutablePointer<Int>.self)
- ptr2.pointee = 11
-
- ptr.deallocate()
1、unsafeBitCast是忽略数据类型的强制转换,不会因为数据类型的变化而改变原来的内存数据
- class Dog {
- var age = 10
- func run() {}
- }
-
- do {
- let dog1 = Dog()
- dog1.age = 10
- dog1.run()
- }
-
- do {
- let dog2 = Dog()
- dog2.age = 10
- dog2.run()
- }