GeekBand~iOS~Swift编程语言~第二周

结构与枚举

结构

struct属于值类型,具有值拷贝语义(赋值与传值)
struct不支持面向对象,主要用于定义轻量级数值类型;class支持面向对象,主要用于设计有丰富关系的组件系统。
struct有传参拷贝成本,不要定义尺寸过大的结构;class有ARC内存管理成本。
不要在struct内定义引用类型属性(会改变struct的值拷贝语义)。

struct VS. class

相同点:
都可以定义以下成员:属性、方法、下标、初始化器
都支持类型扩展、协议
不同点:
类支持继承和多态,结构不支持;
类必须自己定义初始化器,结构会有默认的按成员初始化器;
类支持析构器,结构不支持;
类的实例在堆上,由ARC负责释放;结构的实例在栈上,栈结束自动释放,不参与ARC管理
类支持引用相等比较(===与!==),结构不支持

枚举

enum用于定义一组相关的值成员,enum同属于值类型,具有值拷贝语义(赋值与传参)。
可以使用switch-case语句处理enum,但case必须包含所有的枚举值,否则需要用default。
可以为enum指定原始值,即raw value,类型可以是字符、字符串、整数、浮点数。数值默认从0开始,字符串与枚举值名称相同。
enum支持关联值,可以设置不同类型的值成员,类似联合数据结构
enum还可以定义以下成员:计算属性、方法、初始化器。

继承与多态

继承:子类自动继承基类的属性、方法、下标。
只有类支持继承,结构和枚举不支持继承。
继承同时支持实例成员和类成员。
继承的两层含义:成员复用:子类复用基类成员;类型抽象:将子类当作父类来使用(IS-A关系准则)

继承的内存模型:


模型.png

多态:子类在同一行为接口下,表现不同的实现方式。
子类使用override关键字来表达多态定义。
可以重写的成员有:方法、属性、下标;包括实例成员和类型成员。
在子类的代码中,可以使用super来调用基类的实现。
在成员上使用final阻止子类override该成员;在类上使用final阻止该类被继承。

继承中的init和deinit
初始化器init:
如果子类没有定义初始化器,则将自动继承基类的初始化器;
如果子类定义了初始化器,则不再继承,此时子类初始化器必须调用基类的一个初始化器。如果手工不调用,编译器将自动生成调用;
如果子类初始化器与基类初始化器原型一致,必须使用override;
在子类中使用基类属性,必须确保首先调用基类初始化器
析构器deinit
如果子类没有定义析构器,会自动继承基类析构器;
子类析构器执行完毕后,会自动调用基类析构器(无法手工调用);
子类析构器自动具有多态性

协议

协议:类型的合同约定,只描述外部接口,不提供具体实现。
协议可以包含以下成员:属性、方法、初始化器、下标、操作符。
一个类型可以实现多个协议,协议可以应用在如下类型上。但可以添加class关键字标明协议只能应用在类上:类、结构、枚举。

使用协议:
协议本质上是一种类型,可以作为声明类型,但不能创建实例。
协议变量的内存模型遵从实际类型的内存模型:引用类型传参、拷贝采用传引用方式;值类型传参、拷贝采用传值方式。
检查协议类型:使用is检查类型是否实现了协议;使用as?和as!将类型下溯转型为协议。

协议中的属性:
协议中可以定义只读属性,也可以定义读写属性;
协议中可以定义实例属性,也可以定义类型属性;
协议中只能定义变量属性,不能定义常量属性;
实现协议时,并不要求实现为存储属性、还是计算属性。

协议中的方法:
协议可以定义实例方法,也可以定义类型方法;
协议中的方法不能定义参数的默认值;
针对值类型的mutating协议方法:
值类型(struct,enum)实现的实例方法如果要更改实例本身,需要在协议方法的定义中标明mutating关键字,同时在方法实现时也添加mutating关键字。
添加了mutating的协议方法,对类的实现方法无影响。在类内实现mutating协议方法时,无需再添加mutating关键字。

协议中的初始化器:
协议中可以定义初始化器,但不可以定义析构器。
当class中实现协议定义的初始化器时,需要添加required关键字:
标明子类也需要提供该初始化器;如果定义为final类,则不需要required关键字。
协议可以定义可失败的初始化器init?,具体实现时可以失败、也可以非失败。

更多协议形式:
协议继承:一个协议可以继承一个或多个协议;实现子协议的类型,也必须实现父协议中约定的成员。
协议组合:
可以使用protocol<A,B,...>来组合多个协议。
实现组合协议的类型,必须实现组合协议中的每一个协议。
组合协议是一个临时类型。
可选协议:
协议的某些成员可以定义为optional,不必实现;
可选协议只能应用于class,不能应用于struct和enum;
可选协议必须标明@objc特性(即使不需要和Objective-C互操作)。

字符串

String是一个Unicode编码、16位字符的字符序列。
String与NSString支持无缝互操作。
String被定义为struct,值类型,拷贝时具有值语义。
String是一个struct,但内部包含一个指向堆上的“内容指针”,其指向的对象存放真正的字符串内容。

内存模型

内存模型.png

使用字符串:
使用var和let来控制字符串的可变性;
获取字符串中的字符;
使用append和+连接字符串;
使用字符转义;
字符串插值(String Interpolation)。

copy-on-write共享技术
同一个字符串内容拷贝到不同的变量中时,“内容指针”不变,即不同变量“共享”同一份堆内存。从而实现“节省内存”。
如果某一个变量的字符串内容改变时,先将原来堆内存拷贝一份,“内容指针”指向新的拷贝,然后再更改新的拷贝。从而确保“正确性”。
copy-on-write的目的是实现“内容相同的字符串共享内存,同时又支持字符串随时改变”。
最佳实践:尽量不改变字符串,尽量使用常量字符串let。
copy-on-write--更改前

更改前.png

copy-on-write--更改后

更改后.png

缓存容量与增长:
字符串初始化后,会分配一个缓存容量capacity,其长度一般大于实际的字符数量。
当字符串增长时,如果实际需求大于capacity,其capacity会以二倍的方式指数增长。代价:分配新的堆内存 2*capacity;将原来堆内存上的内容拷贝到新内存;释放原来堆内存。
最佳实践:估计好capacity,预先分配好一定容量,避免以后capacity的增长。

集合类型

集合类型.png

数组:
Array是一个有序的元素序列,支持随机存取,支持动态更新长度。
索引从0开始,索引访问越界会抛出运行时异常。
Array被定义为struct,值类型,拷贝时具有值语义。
Array是一个struct,但内部包含一个指向堆上的“元素指针”,其指向的对象存放真正的数组元素。
1.如果数组元素为值类型,拷贝数组时,元素包含值本身。
2.如果数组元素为引用类型,拷贝数组时,元素引用指向相同的对象。

内存模型:

内存模型.png

使用数组:
使用var和let来控制数组的常量性:数组长度和元素内容都不能更改。
数组遍历:使用for循环访问array[index]需要检查索引越界,具有性能代价;尽可能使用for-in遍历数组元素;或使用Array.enumerate()遍历索引;二者编译器会优化掉索引检查。
尽量避免使用insert和remove操作,因为会改变数组元素序列,涉及到大量的内存拷贝操作,代价较高。

缓存容量与增长
数组初始化后,会分配一个缓存容量capacity,其长度一般大于实际的元素数量
当数组长度增长时,如果实际需求大于capacity,其capacity会以近似二倍的方式指数增长。代价:分配新的堆内存 2*capacity;将原来堆内存上的内容拷贝到新内存;释放原来堆内存。
最佳实践:估计好capacity,预先分配好一定容量,避免以后capacity的增长。
copy-on-write共享技术
同一个数组拷贝到不同的变量中时,“元素指针”不变,即不同变量“共享”同一份堆内存。从而实现“节省内存”。
如果某一个变量的元素内容改变时,先将原来堆内存拷贝一份,“元素指针”指向新的拷贝,然后再更改新的拷贝。从而确保“正确性”。
copy-on-write的目的是实现“元素内容相同的数组共享内存,同时又支持元素随时改变”。
最佳实践:尽量不改变数组元素和长度,尽量使用常量数组。

copy-on-write--更改前

更改前.png

copy-on-write--更改后

更改后.png

集合Set
Set是一个无序的集合,其存储的值不能重复。
Set中的元素必须有哈希值,即支持Hashable协议。
Set被定义为struct,值类型,拷贝时具有值语义。
Set也是一个struct,但内部包含一个指向堆上的“元素指针”,其指向的对象存放真正的元素。

字典Dictionary
Dictionary是一个存储key-value的无序的集合,key唯一,value可重复。
Dictionary中的key必须有哈希值,即支持Hashable协议。
Dictionary被定义为struct,值类型,拷贝时具有值语义。
Dictionary也是一个struct,但内部包含一个指向堆上的“元素指针”,其指向的对象存放真正的元素。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容