2015-12-14 71 views
3

我正在學習Python並希望確認Objective-C和Swift中的特定行爲。當涉及到相同的變量時,Swift Array內存地址發生變化

試驗如下:

的Python

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

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

目標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); 

夫特

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相同,但斯威夫特的打印結果爲:

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

有我丟失的東西?

+0

unsafeAddressOf(數字)不起作用。這裏是錯誤:'錯誤:參數類型'[Int]'不符合期望的類型'AnyObject'' – BridgeTheGap

+0

這可能是一個Xcode版本的東西(它在Xcode 7.2中起作用)。無論如何,我的觀察是,如果你對後面的一些細節感興趣,當你改變一個值類型(而'Array'是一個'struct',一個值類型)時,請參閱後面的部分WWDC 2015視頻[在Swift中使用值類型構建更好的應用程序](https://developer.apple.com/videos/play/wwdc2015-414/)。注意,如果你想在Swift中引用類型行爲,使用'NSMutableArray'(一個'''''',而不是'''''''struct'')。 – Rob

回答

5

Swift中的數組具有值語義,而不是Python和Objective-C中數組的引用語義。你看到不同地址(和地址)的原因是每次你做一個as! AnyObject演員,你實際上告訴Swift橋接你的Array<Int>結構到NSArray的一個實例。既然你連接了三次,你會得到三個不同的地址。


你不應該需要考慮迅捷的數組的地址,但如果你希望(暫時)獲取數組的緩衝區的地址,你可以這樣來做:

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

這使您可以看到緩存的寫入時複製在行動:

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

// the two arrays share a buffer here 
getBufferAddress(numbers)     // "0x00007fba6ad16770" 
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 
getBufferAddress(numbers)     // "0x00007ff23a52cc30" 
getBufferAddress(numbersCopy)    // "0x00007fba6ad16770" 
+0

有沒有什麼辦法像Objective-C那樣獲取地址?或者這在Swift中是不相干的? – BridgeTheGap

+1

Swift中無關緊要!答案中增加了一個註釋。 –