值和引用类型 Value and Reference Types

在Swift中,有两种数据类型. 一是"值类型"(value type), 它是每一个实例都保存有各自的数据,通常定义为struct, enum或tuple. 二是"引用类型"(reference types),它是多实例共享一份数据,这种类型通常定义为class. 在本文中,我们将展示值类型和引用类型各自的优点以及如何在二者之间选择.

它们有什么区别?

最基本的区别是 "值类型"通过拷贝(在赋值,初始化,参数传递中)会创建一个拥有独立数据的实例, 例如:

// 值类型实例
func value_type_example(){
struct S{var data:Int = -}
var a = S()
var b = a // a 拷贝到 b
a.data = // 修改a, b不变
println("\(a.data), \(b.data)") // 打印 42, -1
}

引用类型拷贝, 从另一方面来说, 是隐式的创建了一个共享实例. 在拷贝后, 两个变量实际引用到了同一个实例, 也就是说修改第二个变量的值同样会影响原始值, 例如:

func reference_type_example(){
class C{var data: Int = -}
var x = C()
var y = x // x 拷贝到 y
x.data = // 修改x, 影响到y
println("\(x.data), \(y.data)") // 打印 42, 42
}

可变性在安全的作用(The Role of Mutation in Safety)

一个选择值类型(而不是引用类型)的主要原因是使代码更简单. 如果你总是得到一个唯一, 拷贝的实例, 你就可以确信其它代码不会改变它. 这在多线程环境中非常有效(尤其是不同线程可能修改你的值, 这样容易产生非常难以调试的错误).

因为两者的区别在于数据改变, 因此在实例没有可写数据时, 值类型和引用类型会有相同的场景, 它们的作用是一致的.

你可能想到用值类型,然后,在另一个方面可能是一个不可变类. 这种情况下, 使用NSObject对象可以简化问题, 它同时有值类型的优点. 现在,你可以在Swift中写一个不可变类(只有不可变属性,避免暴露能修改状态的APIs). 实际上, 许多能用Cocoa类(比如NSURL)都设计为不可修改类. 然而, Swift当前并没有提供任何语言机制强迫class不可变(比如子类). 只有struct和enum才强制不可变.

如何选择呢?

如果你需要一个新类型, 你会选哪一种? 当你与Cocoa一起工作时, 许多APIs需要从NSObject子类化, 因此你只有用class. 在其它情况下, 这里有一些指导方针:

使用值类型:

  • 通过==比较实例数据
  • 通过拷贝拥有独立状态
  • 数据在多线程中使用

使用引用类型:

  • 通过===比较实例数据
  • 共享可修改状态

在Swift中, Array,String和Dictionary都是值类型. 它们的行为非常象C中的简单int值, 每个实例都有独立的数据. 你不需要做任何其它事情(比如拷贝)来阻止其它代码来修改数据. 重要的是, 你可以安全的在线程之间传递变量不需要处理同步问题. 在改善安全性的思路下, 这样的模型将帮助你编写可预知的代码.

iOS: 学习笔记, 值与引用类型(译自: https://developer.apple.com/swift/blog/ Aug 15, 2014 Value and Reference Types)的更多相关文章

  1. iOS: 学习笔记, 透过Boolean看Swift(译自: https://developer.apple.com/swift/blog/ Aug 5, 2014 Boolean)

    透过Boolean看Swift 一个简单的Bool类型内部就包含了许多Swift主要功能, 如何构建一个简单类型是有趣的演示. 本文将创建一个与Bool类型在设计与实现上非常相似的新MyBool类型. ...

  2. iOS学习笔记(一)——ios搭建开发环境

    好久就想试水IOS开发了,由于开发环境限制,一直局限于理论和虚拟机,近来入手了MacBook Pro,也来尝尝鲜,笔者也是现学现总结,如果有不足,请指正. IOS开发必备MAC OS X 另加一部iP ...

  3. iOS学习笔记——AutoLayout的约束

    iOS学习笔记——AutoLayout约束 之前在开发iOS app时一直以为苹果的布局是绝对布局,在IB中拖拉控件运行或者直接使用代码去调整控件都会发上一些不尽人意的结果,后来发现iOS在引入了Au ...

  4. iOS学习笔记-精华整理

    iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始 ...

  5. iOS学习笔记10-UIView动画

    上次学习了iOS学习笔记09-核心动画CoreAnimation,这次继续学习动画,上次使用的CoreAnimation很多人感觉使用起来很繁琐,有没有更加方便的动画效果实现呢?答案是有的,那就是UI ...

  6. iOS学习笔记总结整理

    来源:http://mobile.51cto.com/iphone-386851_all.htm 学习IOS开发这对于一个初学者来说,是一件非常挠头的事情.其实学习IOS开发无外乎平时的积累与总结.下 ...

  7. iOS学习笔记之ARC内存管理

    iOS学习笔记之ARC内存管理 写在前面 ARC(Automatic Reference Counting),自动引用计数,是iOS中采用的一种内存管理方式. 指针变量与对象所有权 指针变量暗含了对其 ...

  8. IOS学习笔记06---C语言函数

    IOS学习笔记06---C语言函数 --------------------------------------------  qq交流群:创梦技术交流群:251572072              ...

  9. IOS学习笔记48--一些常见的IOS知识点+面试题

      IOS学习笔记48--一些常见的IOS知识点+面试题   1.堆和栈什么区别? 答:管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制:对于堆来说,释放工作由程序员控制,容易产生memor ...

随机推荐

  1. GUI(图形用户界面)

    一.GUI(图形用户界面) GUI Graphical User Interface(图形用户接口) 用图形的方式,来显示计算机操作的界面,这样更方便更直观 CLI Command line User ...

  2. Java或web中解决所有路径问题

    Java开发中使用的路径,分为两种:绝对路径和相对路径.归根结底,Java本质上只能使用绝对路径来寻找资源.所有的相对路径寻找资源的方法,都不过是一些便利方法.不过是API在底层帮助我们构建了绝对路径 ...

  3. ngnix apache tomcat集群负载均衡配置

    http://w.gdu.me/wiki/Java/tomcat_cluster.html 参考: Tomcat与Apache或Nginx的集群负载均衡设置: http://huangrs.blog. ...

  4. qemu 的方式安装debian 模拟powerpc

    http://bbs.pediy.com/showthread.php?p=1424746http://www.ibm.com/developerworks/cn/linux/l-qemu/ 线总结下 ...

  5. Java基础知识强化之IO流笔记25:FileInputStream / FileOutputStream 复制图片案例

    1.  需求:把D:\\美女.jpg 复制到当前项目目录下mn.jpg 代码示例: package com.himi.filecopy; import java.io.FileInputStream; ...

  6. WPF学习之资源-Resources

    WPF学习之资源-Resources WPF通过资源来保存一些可以被重复利用的样式,对象定义以及一些传统的资源如二进制数据,图片等等,而在其支持上也更能体现出这些资源定义的优越性.比如通过Resour ...

  7. 一个小时成功安装SQL Server 2012图解教程

    在安装微软最新数据库SQL Server 2012之前,编者先确定一下安装环境:Windonws 7 SP1,32位操作系统.CPU是2.1GHz赛扬双核T3500,内存2.93GB. 安装SQL S ...

  8. Chrome浏览器离线下载地址(Stable/Beta/Dev)

    最新稳定版:https://www.google.com/intl/zh-CN/chrome/browser/?standalone=1 最新测试版:https://www.google.com/in ...

  9. C#将DataTable导出Execl、Word、Xml

        /// <summary>     /// 将DT转换为Execl的方法     /// </summary>     /// <param name=" ...

  10. 使用jquery.validate.js实现boostrap3的校验和验证

    使用jquery.validate.js实现boostrap3的校验和验证 boostrap3验证框架 jquery.validate.js校验表单 >>>>>>& ...