PART_A 类&结构体对比
共同点
定义属性:存储值
定义方法:提供功能
定义附属脚本:访问值
定义构造器:生成初始化值
通过扩展增加默认实现的功能
实现协议以提供某种标准功能
类的附加功能
语法格式
struct Resolution {
var width = 0
var height = 0
}
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
}
实例创建
let demoResolution = Resolution()
let demoVideoMode = VideoMode()
属性访问&变量属性赋值
结构体类型的成员逐一构造器
PART_B 结构体和枚举是值类型
所有基本类型(整型Integer、浮点型Float、布尔型Boolean、字符串String、数组Array、字典Dictionary)、枚举、结构体都是值类型. 赋值时仅为拷贝副本
let hd = Resolution(width: 1920,height: 1080)
var cinema = hd
cinema.width = 2048
类是引用类型:引用的是已存在的实例本身而不是其拷贝
let tenEighty = VideoMode()
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0
let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0
// tenEighty.frameRate 值为 30.0
需要注意的是 tenEighty 和 alsoTenEighty 被声明为常量而不是变量. 然而你依然可以改变 tenEighty.frameRate 和 alsoTenEighty.frameRate,因为 tenEighty 和 alsoTenEighty 这两个常量的值并未改变. 它们并不“存储”这个 VideoMode 实例,而仅仅是对 VideoMode 实例的引用. 所以,改变的是被引用的 VideoMode 的 frameRate 属性,而不是引用 VideoMode 的常量的值
恒等运算:===
、==
===
:两个类类型的常量或变量引用同一个类实例
==
:两个实例的值相等
指针
PART_C 类和结构体的选择
大部分场景还是需要定义类,生成实例,通过引用来管理和传递
结构体场景
该数据结构的主要目的是封装少量相关简单数据值
有理由预计该数据结构的实例在被赋值或传递时,封装的数据将会被拷贝而不是被引用
该数据结构中存储的值类型属性,也应该被拷贝,而不是被引用
该数据结构不需要去继承另一个既有类型的属性或者行为
如定义几何形状:长宽高、三维坐标系内一点:xyz等
补充
1..Swift String
、Array
、Dictionary
以结构体的形式实现,即被赋值给新的常量或变量、或被传入方法中时,其值会被拷贝
2..OC 中 NSString
、NSArray
、NSDictionary
类型均以类的形式实现,其不会发生值拷贝,而是传递现有实例的引用
以上。如有错误和疑问,欢迎指正提出。catface.wyh@gmail.com