2016-02-05 110 views
0

在這裏,似乎有很多困惑和不同的意見,我想知道,迅速做出對象的淺拷貝而不是深拷貝是可能的。在swift中創建集合類(Array,Dictionary)的淺表副本,而不是深層副本。

我在JAVA中登記 - http://www.jusfortechies.com/java/core-java/deepcopy_and_shallowcopy.php,它清楚地解釋了淺拷貝和深拷貝之間的區別,但我沒有在swift中得到一個例子。

我試過initWithArray:copyItems:檢查當我更改copyItems的布爾標誌時,它會產生什麼差別,但是我看不到任何區別。我應該通過更改copyItems標誌來區分淺拷貝或深拷貝,但是我錯了,它總是創建一個深層拷貝。

請檢查我的下面的代碼,我使用initWithArray將copyObject對象arrayObject1複製到arrayObject2:copyItems:通過將copyItems:設置爲true。我將arrayObject2的第0個字符串對象更改爲新的字符串對象,並將arrayObject2的第0個對象更改,但是arrayObject1第0個對象未更改。而如果我通過將copyItems:賦值爲false來複制它,那麼我也得到了相同的結果。

那麼如何實現淺拷貝,如果它不是通過initWithArray:copyItems:那麼什麼copyItems:標誌對結果產生影響。

func createAnArrayUsingArrayCopyItems(){ 

     let name = "albort" 
     let arrayObject1 = NSArray.init(objects: name, 15) 
     let arrayObject2 = NSMutableArray.init(array: arrayObject1 as [AnyObject], copyItems: true) 
     arrayObject2[0] = "john" 
     print(arrayObject1) 
     print(arrayObject2) 

    } 

輸出 - >
enter image description here

回答

1

這是因爲name是Swift String實例。字符串是結構體,因此它是一個值類型。那是因爲它總是被價值複製。 arrayObject1 as [AnyObject]是一個轉換爲swift數組(也是一個結構體),其中包含String對象。

因此,在Swift中使用像Array和String這樣的結構來獲得淺拷貝並不是一件容易的事。

我只能拿出拳擊結構實例的想法變成一個類包裝:

class StringBox : CustomStringConvertible, NSCopying { 
    var string: String 

    init(str: String) { 
    string = str 
    } 

    var description: String { 
    return "\(string)" 
    } 

    @objc func copyWithZone(zone: NSZone) -> AnyObject { 
    return StringBox(str: string) 
    } 
} 

func createAnArrayUsingArrayCopyItems(){ 
    let name = StringBox(str: "albort") 
    let arrayObject1 = NSArray.init(objects: name, 15) 
    let arrayObject2 = NSMutableArray.init(array: arrayObject1 as [AnyObject], copyItems: false) 
    (arrayObject2[0] as! StringBox).string = "john" 
    print(arrayObject1[0]) 
    print(arrayObject2[0]) 
} 

createAnArrayUsingArrayCopyItems() 

它給了我下面的輸出:

john 
john 
+0

嗨,欣賞你的答案是事實。但如果你能幫助我,我還有其他問題。我改變了copyItems:標誌爲真,這是由**崩潰'NSArrayThoroughConcept.StringBox'沒有實現methodSignatureForSelector: - 麻煩未來 - 無法識別的選擇器 - [NSArrayThoroughConcept.StringBox copyWithZone:] **我可以知道它是什麼讓變化改變國旗true/false – KiranJasvanee

+1

@Kiran我編輯了我的答案。您應該採用'NSCopying'並實施'copyWithZone:'方法以支持深度複製。標誌'copyItems'確定數組項是否通過引用被複制(然後通過複製對象指針與適當的ARC工作來複制)或通過值(然後您應該提供複製類的項目的方法)。 – slashdot

+0

其實這就是我想知道的,並學習如何通過**數組幫助實現淺層和深層複製:copyItems ** – KiranJasvanee

1

arrayObject2[0] = "john"

這改變了該項目位置0中陣列2 - 這已經在該位置存在的字符串不是內容的陣列。要做到這一點,它需要是一個可變字符串數組。

事實上,如果您創建帶有可變字符串的數組,然後追加到數組2中位置0的字符串中,您將看到數組1中相同的字符串實例也會更新(因爲它是相同的實例)。

編輯數組實例與編輯數組中的實例不同。

如果你問它,副本很淺。從技術上講,淺層和深層複製有時是數據類型的同一事物是不可變的。

+0

我明白你的回答,能否請您解釋與一些代碼通過使用NSMutableString這不是不可改變的 – KiranJasvanee