原创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是值类型

struct S{
    var num = -1
}
var a = S()
var b = a
a.num = 10
print(b.num) //-1

可以看到,值类型拷贝后的内存是这个样子的

再来看看引用类型

class S{
    var num = -1
}
var a = S()
var b = a
a.num = 10
print(b.num) // 10

总结

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

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

  • Class的实例是引用类型
  • Swift方法类型是引用类型(在Swift中,方法也是一种类型)
  • 其余的都是值类型,像Array,Dictionary本质都是Struct。

值类型的优点

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

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

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

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

用值类型

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

引用类型

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

copy/Mutablecopy

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

let str1 = Nsstring(string: "123")
   let str2 = str1.copy() as!  Nsstring
   let str3 = str1.mutablecopy() as! NSMutableString
   NSLog("最初: %p",str1)
   NSLog("copy: %p",str2)
   NSLog("mutablecopy: %p",str3)

可以看到Log

2015-12-01 12:07:41.861 SWTest[1082:40543] 最初: 0x7fd1d3d74cb0
2015-12-01 12:07:41.862 SWTest[1082:40543] copy: 0x7fd1d3d74cb0
2015-12-01 12:07:41.862 SWTest[1082:40543] mutablecopy: 0x7fd1d3d18c80

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

  • copy 是浅拷贝,只拷贝指针
  • mutablecopy 是深拷贝,拷贝了value

对于可变类型,举例NSMutableString

let str1 = NSMutableString(string: "123")
  let str2 = str1.copy() as!  Nsstring
  let str3 = str1.mutablecopy() as! NSMutableString
  NSLog("最初: %p",str1)
  NSLog("copy: %p",str2)
  NSLog("mutablecopy: %p",str3)

可以看到Log

2015-12-01 12:10:35.721 SWTest[1113:43822] 最初: 0x7fba89e8a850
2015-12-01 12:10:35.721 SWTest[1113:43822] copy: 0xa000000003332313
2015-12-01 12:10:38.006 SWTest[1113:43822] mutablecopy: 0x7fba89e8a960

可以看到,对于可变类型

  • copy 深拷贝,拷贝了value
  • mutablecopy 是深拷贝,拷贝了value

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

func logArrayElementPointAddeRSS(array:NSArray,description:String){
        for element in array{
            let object = element as! NSObject
            NSLog("%@: %p",description,object)
        }
    }

然后

let array = NSArray(arrayLiteral: Nsstring(string: "123"),NSNumber(int: 12))
        let array1 = array.copy() as!  NSArray
        let array2 = array.mutablecopy() as! NSMutableArray
        NSLog("最初: %p",array)
        NSLog("copy: %p",array1)
        NSLog("mutablecopy: %p",array2)

        logArrayElementPointAddeRSS(array,description: "最初")
        logArrayElementPointAddeRSS(array1,description: "copy后")
        logArrayElementPointAddeRSS(array2,description: "mutablecopy后")

看看Log

2015-12-01 12:18:46.252 SWTest[1156:50909] 最初: 0x7f9c304afcb0
2015-12-01 12:18:46.253 SWTest[1156:50909] copy: 0x7f9c304afcb0
2015-12-01 12:18:46.253 SWTest[1156:50909] mutablecopy: 0x7f9c30403980
2015-12-01 12:18:46.255 SWTest[1156:50909] 最初: 0x7f9c304b4d30
2015-12-01 12:18:46.255 SWTest[1156:50909] 最初: 0xb0000000000000c2
2015-12-01 12:18:46.255 SWTest[1156:50909] copy后: 0x7f9c304b4d30
2015-12-01 12:18:46.256 SWTest[1156:50909] copy后: 0xb0000000000000c2
2015-12-01 12:18:46.256 SWTest[1156:50909] mutablecopy后: 0x7f9c304b4d30
2015-12-01 12:18:46.256 SWTest[1156:50909] mutablecopy后: 0xb0000000000000c2

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

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

画个图加深理解
对于NSArray的copy

对于NSArray的Mutablecopy

对于可变集合

let array = NSMutableArray(arrayLiteral: Nsstring(string: "123"),description: "mutablecopy后")

可以看到Log

2015-12-01 12:31:22.818 SWTest[1209:61916] 最初: 0x7f937ad73d90
2015-12-01 12:31:22.818 SWTest[1209:61916] copy: 0x7f937ad91fb0
2015-12-01 12:31:22.819 SWTest[1209:61916] mutablecopy: 0x7f937ad73190
2015-12-01 12:31:22.819 SWTest[1209:61916] 最初: 0x7f937ac0c100
2015-12-01 12:31:22.820 SWTest[1209:61916] 最初: 0xb0000000000000c2
2015-12-01 12:31:22.820 SWTest[1209:61916] copy后: 0x7f937ac0c100
2015-12-01 12:31:22.820 SWTest[1209:61916] copy后: 0xb0000000000000c2
2015-12-01 12:31:22.820 SWTest[1209:61916] mutablecopy后: 0x7f937ac0c100
2015-12-01 12:31:22.820 SWTest[1209:61916] mutablecopy后: 0xb0000000000000c2

可以看到,对于可变集合

  • 对于集合本身,copy拷贝了value
  • 对于集合本身,Mutablecopy拷贝了value
  • 对于集合中存储的对象,不管是copy还是mutablecopy,都是浅拷贝

最后

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

Swift 值类型,引用类型,深拷贝,浅拷贝,Copy,MutableCopy的更多相关文章

  1. Swift基础语法: 23 - Swift的Trailing闭包, 捕获, 闭包是引用类型

    其使用求余运算符计算最后一位数字并利用digitNames字典获取所映射的字符串.2.字典digitNames下标后跟着一个叹号(!

  2. swift 值类型和引用类型

    1.Struct是值类型,拷贝是值拷贝,Class是引用类型,拷贝是引用拷贝

  3. Swift:什么时候使用结构体和类

    发布于2015年8月14日世界上对swift持续不断的讨论话题中有一个就是什么时候使用结构体什么时候使用类。这个例子对应下面Swift的举例:和之前的打印结果一样:值类型的体验值类型不是一个新的概念,但是对于很多人来说他们觉得这是新的。很多认为“一切皆对象”的语言如Python、JavaScript等也都只有引用类型。Swift对此说“yes”,那也就意味着Array,Dictionary和String都是结构体而不是类。

  4. 何时使用Swift Structs和Classes

    struct在绝大部分Objective-C代码中并不是很常用.我们偶尔以CGRect和CGPoint等方式接触到它们,但很少会自己去写.首先,它们不是很实用.用Objective-C在struct中正确地存储对象的引用的确很难,尤其是使用ARC的时候.很多其他语言干脆没有类似struct的东东.许多语言如同Python和JavaScript一样”万物皆对象”,只有引用类型.如果你是从这类语言转型到Swift的,你可能对struct的概念就更陌生了.等一下!

  5. Swift学习笔记(七)类和结构体

    储存属性是捆绑和储存在类或结构体中的常量或变量。定义了一个名为VideoMode的类创建类和结构体的实例属性访问注意:与Objective-C语言不同的是,Swift允许直接设置结构体属性的子属性。在Swift中,所有的基本类型:整数、浮点数、布尔值、字符串、数组和字典,都是值类型,并且都是以结构体的形式在后台所实现。在Swift中,所有的结构体和枚举都是值类型。实际中,这意味着绝大部分的自定义数据构造都应该是类,而非结构体。

  6. Swift学习笔记—— 类和结构体

  7. 关于Swift中的值类型(Value Types)与引用类型(Reference Type)

    Swift里面的类型分为两种:●值类型:每个实例都保留了一分独有的数据拷贝。如结构体、枚举和元组。值类型与引用类型的区别在于:值类型和引用类型最基本的区别在于复制之后的结果。引用类型示例代码如下:值类型较引用类型来说,会让你更容易在大量代码中理清状况。因此可能会造成严重的程序错误,这在调试过程中非常难以排除。

  8. Swift面向协议编程初探

    最近有时间,挑了几个今年WWDC中比较感兴趣的Session视频来学习,今天就抽时间整理一下关于Swift2.0中一个比较新的概念面向协议编程。苹果官方那么正式的称Swift是一门支持面向协议编程的语言,难道就是这么简单的内容?而在Swift语言中,协议被赋予了更多的功能和更广阔的使用空间,在Swift2.0中,更为协议增加了扩展功能,使其能够胜任绝大多数情况下数据类型的抽象,所以苹果开始声称Swift是一门支持面向协议编程的语言。

  9. Swift 中数组和链表的性能

    尽管如此,我觉得链表的例子非常有意思,而且值得实现和把玩,它有可能会提升数组reduce方法的性能。同时我认为Swift的一些额外特性很有趣:比如它的枚举可以灵活的在对象和具体方法中自由选择,以及“默认安全”。这本书未来的版本可能就会用Swift作为实现语言。拷贝数组消耗的时间是线性的。使用链表还有其他的代价——统计链表节点的个数所需要的时间是统计数组元素个数时间的两倍,因为遍历链表时的间接寻址方式是需要消耗时间的。

  10. swift 类和结构体

    swift的编码风格是类class和结构体struct名字使用大写字母开头的匈牙利表示法,相反的。类的方法和属性则用小写字母开头的匈牙利表示法。结构体总是通过被复制而进行代码传递的。表示是否是引用到同一个类对象7:类和结构体区别。结构体是值类型,结构体的赋值意味着拷贝行为的发生。swift的数组和字典都是以值类型传递的。

随机推荐

  1. Swift UITextField,UITextView,UISegmentedControl,UISwitch

    下面我们通过一个demo来简单的实现下这些控件的功能.首先,我们拖将这几个控件拖到storyboard,并关联上相应的属性和动作.如图:关联上属性和动作后,看看实现的代码:

  2. swift UISlider,UIStepper

    我们用两个label来显示slider和stepper的值.再用张图片来显示改变stepper值的效果.首先,这三个控件需要全局变量声明如下然后,我们对所有的控件做个简单的布局:最后,当slider的值改变时,我们用一个label来显示值的变化,同样,用另一个label来显示stepper值的变化,并改变图片的大小:实现效果如下:

  3. preferredFontForTextStyle字体设置之更改

    即:

  4. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 字典实战和UIKit初探

    ios中数组和字典的应用Applicationschedule类别子项类别名称优先级数据包contactsentertainment接触UIKit学习用Swift调用CocoaTouchimportUIKitletcolors=[]varbackView=UIView(frame:CGRectMake(0.0,0.0,320.0,CGFloat(colors.count*50)))backView

  6. swift语言IOS8开发战记21 Core Data2

    上一话中我们简单地介绍了一些coredata的基本知识,这一话我们通过编程来实现coredata的使用。还记得我们在coredata中定义的那个Model么,上面这段代码会加载这个Model。定义完方法之后,我们对coredata的准备都已经完成了。最后强调一点,coredata并不是数据库,它只是一个框架,协助我们进行数据库操作,它并不关心我们把数据存到哪里。

  7. swift语言IOS8开发战记22 Core Data3

    上一话我们定义了与coredata有关的变量和方法,做足了准备工作,这一话我们来试试能不能成功。首先打开上一话中生成的Info类,在其中引用头文件的地方添加一个@objc,不然后面会报错,我也不知道为什么。

  8. swift实战小程序1天气预报

    在有一定swift基础的情况下,让我们来做一些小程序练练手,今天来试试做一个简单地天气预报。然后在btnpressed方法中依旧增加loadWeather方法.在loadWeather方法中加上信息的显示语句:运行一下看看效果,如图:虽然显示出来了,但是我们的text是可编辑状态的,在storyboard中勾选Editable,再次运行:大功告成,而且现在每次单击按钮,就会重新请求天气情况,大家也来试试吧。

  9. 【iOS学习01】swift ? and !  的学习

    如果不初始化就会报错。

  10. swift语言IOS8开发战记23 Core Data4

    接着我们需要把我们的Rest类变成一个被coredata管理的类,点开Rest类,作如下修改:关键字@NSManaged的作用是与实体中对应的属性通信,BinaryData对应的类型是NSData,CoreData没有布尔属性,只能用0和1来区分。进行如下操作,输入类名:建立好之后因为我们之前写的代码有些地方并不适用于coredata,所以编译器会报错,现在来一一解决。

返回
顶部