ios - 引用同一变量时,Swift 数组内存地址发生变化

标签 ios swift pointers memory-address

我正在学习 Python,想确认 Objective-C 和 Swift 中的某种行为。

测试如下:

python

def replace(list):
    list[0] = 3
    print(list)

aList = [1, 2, 3]
print(aList)
replace(aList)
print(aList)

objective-C

- (void)replace:(NSMutableArray *)array {
    array[0] = @1;
    NSLog(@"array: %@, address: %p\n%lx", array, array, (long)&array);
}

NSMutableArray *array = [@[@1, @2, @3] mutableCopy];
NSLog(@"original: %@, address: %p \n%lx", array, array, (long)&array);
[self replace:array];
NSLog(@"modified: %@, address: %p \n%lx", array, array, (long)&array);

swift

var numbers = [1, 2, 3]
let replace = { (var array:[Int]) -> Void in
    array[0] = 2
    print("array: \(array) address:\(unsafeAddressOf(array as! AnyObject))")
}

print("original: \(numbers) address:\(unsafeAddressOf(numbers as! AnyObject))")
replace(numbers)
print("modified: \(numbers) address:\(unsafeAddressOf(numbers as! AnyObject))")

除 Swift 中的地址部分外,所有结果均符合预期。在Objective-C中,数组的地址在originalmodified中保持不变,但是Swift的打印结果是:

original: [1, 2, 3] address:0x00007f8ce1e092c0
array: [2, 2, 3] address:0x00007f8ce1f0c5d0
modified: [1, 2, 3] address:0x00007f8ce4800a10

有什么我想念的吗?

最佳答案

Swift 中的数组具有值语义,而不是 Python 和 Objective-C 中数组的引用语义。您看到不同地址(和所有地址)的原因是每次您执行 as! AnyObject cast,你实际上是在告诉 Swift 桥接你的 Array<Int>结构到 NSArray 的一个实例.由于桥接了 3 次,因此您获得了三个不同的地址。


你不需要考虑 Swift 数组的地址,但如果你想(暂时)获取数组缓冲区的地址,你可以这样做:

func getBufferAddress<T>(array: [T]) -> String {
    return array.withUnsafeBufferPointer { buffer in
        return String(reflecting: buffer.baseAddress)
    }
}

这让您可以看到缓冲区的写时复制操作:

var numbers = [1, 2, 3]
let numbersCopy = numbers

// the two arrays share a buffer here
print(getBufferAddress(numbers))                 // "0x00007fba6ad16770"
print(getBufferAddress(numbersCopy))             // "0x00007fba6ad16770"

// mutating `numbers` causes a copy of its contents to a new buffer
numbers[0] = 4

// now `numbers` has a new buffer address, while `numbersCopy` is unaffected
print(getBufferAddress(numbers))                 // "0x00007ff23a52cc30"
print(getBufferAddress(numbersCopy))             // "0x00007fba6ad16770"

关于ios - 引用同一变量时,Swift 数组内存地址发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34259513/

相关文章:

pointers - Fortran 指针赋值可以通过类型绑定(bind)的泛型过程重载吗?

c - 如何修改char *的值?

iphone - 新的 ViewControllers 导致黑屏

ios - 如何在 CAShapeLayer 中制作动态 strokeColor?在 swift

ios - iPhone 的 UIButton 的 UIPopOver

swift - 将 SecKey 保存和读取到钥匙串(keychain)

c - WIN32和其他c字符串的区别

ios - 使用默认数据集创建 CoreData 模型

ios - 从后台线程调用时在 iPad 上延迟

ios - 如何使 Xcode 8.2.1 显示导致异常的行?