Swift 值类型,引用类型,深拷贝,浅拷贝,Copy,MutableCopy

前端之家收集整理的这篇文章主要介绍了Swift 值类型,引用类型,深拷贝,浅拷贝,Copy,MutableCopy前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

原创Blog,转载请注明出处
http://blog.csdn.net/hello_hwc?viewmode=list
我的stackoverflow


前言:Swift相对应Objective C来说,它不再需要绝大部分对象继承自NSObject,所以Swift的类型和Objective C的变量类型也不一致。


Value Type/Reference Type

什么是值类型,引用类型?

二者最主要的差别在于当copy发生的时候,注意,当在Swift中使用赋值符号的时候发生的都是copy,这个在最后我会解释为什么。

Struct是值类型

  1. struct S{
  2. var num = -1
  3. }
  4. var a = S()
  5. var b = a
  6. a.num = 10
  7. print(b.num) //-1@H_404_44@
  8. 可以看到,值类型拷贝后的内存是这个样子的

  9. 再来看看引用类型

  10. class S{
  11.     var num = -1
  12. }
  13. var a = S()
  14. var b = a
  15. a.num = 10
  16. print(b.num) // 10@H_404_44@ 
  17.   
  18.  

    总结

  19.  
  20. 值类型或者引用类型在赋值的时候都是Copy,值类型拷贝累实际的内存(value),而饮用类型只是拷贝了指针,仍然指向最开始的内存区域

  21.  
  22.  

    什么是值类型or 引用类型?

  23.  
    • Class的实例是引用类型
    • Swift方法类型是引用类型(在Swift中,方法也是一种类型)
    • 其余的都是值类型,像ArrayDictionary本质都是Struct
  24.  
  25.  

    值类型的优点

  26.  
  27. 优点还是很明显的,每次得到的都是一个Copy,这样就可以放心的运行,没必要担心其他代码修改这个值。尤其是在多线程环境里。

  28.  

    值类型每次都会进行Copy吗?

  29.  
  30. 并不是每次都是要copy的,当值并不会改变的时候,Swift并不会进行copy。例如let a = 1;let b = a.

  31.  
  32.  

    什么时候用值类型/引用类型?

  33.  

    用值类型

  34.  
    • 当你希望用==来比较的时候
    • 赋值后有独立的状态
    • 数据在多线程中使用
  35.  

    引用类型

  36.  
    • 当你希望用===来比较的时候(注意,这里三个等号)
    • 创建共享的可变数据
  37.  
  38.  

    Copy/MutableCopy

  39.  

    对于不可变类型,举例NSString
    代码

  40.  
    let str1 = NSString(string: "123")
  41.    let str2 = str1.copy() as!  NSString
  42.    let str3 = str1.mutableCopy() as! NSMutableString
  43.    NSLog("最初: %p",str1)
  44.    NSLog("copy: %p",str2)
  45.    NSLog("mutableCopy: %p",str3)@H_404_44@ 
  46.  

    可以看到Log

  47.  
    2015-12-01 12:07:41.861 SWTest[1082:40543] 最初: 0x7fd1d3d74cb0
  48. 2015-12-01 12:07:41.862 SWTest[1082:40543] copy: 0x7fd1d3d74cb0
  49. 2015-12-01 12:07:41.862 SWTest[1082:40543] mutableCopy: 0x7fd1d3d18c80@H_404_44@ 
  50.  

    可以看到,对于不可变类型

  51.  
    • copy 是浅拷贝,只拷贝指针
    • mutableCopy 是深拷贝,拷贝了value
  52.  

    对于可变类型,举例NSMutableString

  53.  
    let str1 = NSMutableString(string: "123")
  54.   let str2 = str1.copy() as!  NSString
  55.   let str3 = str1.mutableCopy() as! NSMutableString
  56.   NSLog("最初: %p",str1)
  57.   NSLog("copy: %p",str2)
  58.   NSLog("mutableCopy: %p",str3)@H_404_44@ 
  59.  

    可以看到Log

  60.  
    2015-12-01 12:10:35.721 SWTest[1113:43822] 最初: 0x7fba89e8a850
  61. 2015-12-01 12:10:35.721 SWTest[1113:43822] copy: 0xa000000003332313
  62. 2015-12-01 12:10:38.006 SWTest[1113:43822] mutableCopy: 0x7fba89e8a960@H_404_44@ 
  63.  

    可以看到,对于可变类型

  64.  
    • copy 深拷贝,拷贝了value
    • mutableCopy 是深拷贝,拷贝了value
  65.  

    对于不可变集合
    线写一个辅助方法,打印NSArray中对象指向的地址

  66.  
    func logArrayElementPointAddeRSS(array:NSArray,description:String){
  67.         for element in array{
  68.             let object = element as! NSObject
  69.             NSLog("%@: %p",description,object)
  70.         }
  71.     }@H_404_44@ 
  72.  

    然后

  73.  
    let array = NSArray(arrayLiteral: NSString(string: "123"),NSNumber(int: 12))
  74.         let array1 = array.copy() as!  NSArray
  75.         let array2 = array.mutableCopy() as! NSMutableArray
  76.         NSLog("最初: %p",array)
  77.         NSLog("copy: %p",array1)
  78.         NSLog("mutableCopy: %p",array2)
  79.         logArrayElementPointAddeRSS(array,description: "最初")
  80.         logArrayElementPointAddeRSS(array1,description: "copy后")
  81.         logArrayElementPointAddeRSS(array2,description: "mutableCopy后")@H_404_44@ 
  82.  

    看看Log

  83.  
    2015-12-01 12:18:46.252 SWTest[1156:50909] 最初: 0x7f9c304afcb0
  84. 2015-12-01 12:18:46.253 SWTest[1156:50909] copy: 0x7f9c304afcb0
  85. 2015-12-01 12:18:46.253 SWTest[1156:50909] mutableCopy: 0x7f9c30403980
  86. 2015-12-01 12:18:46.255 SWTest[1156:50909] 最初: 0x7f9c304b4d30
  87. 2015-12-01 12:18:46.255 SWTest[1156:50909] 最初: 0xb0000000000000c2
  88. 2015-12-01 12:18:46.255 SWTest[1156:50909] copy后: 0x7f9c304b4d30
  89. 2015-12-01 12:18:46.256 SWTest[1156:50909] copy后: 0xb0000000000000c2
  90. 2015-12-01 12:18:46.256 SWTest[1156:50909] mutableCopy后: 0x7f9c304b4d30
  91. 2015-12-01 12:18:46.256 SWTest[1156:50909] mutableCopy后: 0xb0000000000000c2@H_404_44@ 
  92.  

    可以看到,对于不可变集合

  93.  
    • 对于集合本身,Copy只是拷贝了指针,指针仍然指向最初的Array对象
    • 对于集合本身,MutableCopy拷贝了value
    • 对于集合中存储的对象,不管是copy还是mutableCopy,都是浅拷贝。
  94.  

    画个图加深理解
    对于NSArrayCopy

  95.  

    对于NSArrayMutableCopy

  96.   
  97.  

    对于可变集合

  98.  
    let array = NSMutableArray(arrayLiteral: NSString(string: "123"),description: "mutableCopy后")@H_404_44@ 
  99.  

    可以看到Log

  100.  
    2015-12-01 12:31:22.818 SWTest[1209:61916] 最初: 0x7f937ad73d90
  101. 2015-12-01 12:31:22.818 SWTest[1209:61916] copy: 0x7f937ad91fb0
  102. 2015-12-01 12:31:22.819 SWTest[1209:61916] mutableCopy: 0x7f937ad73190
  103. 2015-12-01 12:31:22.819 SWTest[1209:61916] 最初: 0x7f937ac0c100
  104. 2015-12-01 12:31:22.820 SWTest[1209:61916] 最初: 0xb0000000000000c2
  105. 2015-12-01 12:31:22.820 SWTest[1209:61916] copy后: 0x7f937ac0c100
  106. 2015-12-01 12:31:22.820 SWTest[1209:61916] copy后: 0xb0000000000000c2
  107. 2015-12-01 12:31:22.820 SWTest[1209:61916] mutableCopy后: 0x7f937ac0c100
  108. 2015-12-01 12:31:22.820 SWTest[1209:61916] mutableCopy后: 0xb0000000000000c2@H_404_44@ 
  109.  

    可以看到,对于可变集合

  110.  
    • 对于集合本身,Copy拷贝了value
    • 对于集合本身,MutableCopy拷贝了value
    • 对于集合中存储的对象,不管是copy还是mutableCopy,都是浅拷贝
  111.   
  112.  
  113.  

    最后

  114.  

    欢迎关注LeoCSDN博客,我会持续更新iOS/Objective C/Swift相关的博客

猜你在找的Swift相关文章