Swift语法(五)

一.自动引用计数

1.自动引用计数工作机制

1.1 swift和oc一样,采用自动引用计数来管理内存

1.2 当有强引用指向对象,对象的引用计数 +1 , 强引用消失,自动计数 -1

1.3 如果对象的引用计数为0 , 那么该对象会被销毁

2.循环引用

2.1 什么是循环引用?

两个(或多个)对象互相强引用

2.2 循环引用对项目有什么影响

循环引用会让对象不会被销毁,一直保存在内存中,可能导致项目运行不畅

2.3 怎么解决强引用问题?

只需要让其中一个对象对另外一个对象的引用变为弱引用即可

在swift中用waek 相当于OC中的 __weak ,或者使用 unowned 相当于OC中的 __unsafe_unretained

3.weak 和 unowned的区别

3.1 相同点:
都是一个弱引用,不会对对象进行retain

3.2 不同点

3.21 weak(__weak) :当弱引用指向的对象销毁时,该引用会指向nil 所以用weak指向的数据类型为可选类型

3.22 unowned(__unsafe_unretained) :当弱引用指向的对象销毁时,依然指向原来的内存地址, 容易产生错误(野指针/访问僵尸对象)

3.23 unowned不支持可选类型

二.可选链

1.什么是可选链?

简单的说,就是可选类型的对象组成的链条

2.为什么会产生可选链?

2.1 假设有三个类, 人,狗,玩具

2.2 人里面有狗这个属性,狗里面有玩具这个属性, 玩具里面有价格这个属性

2.3 把玩具这个对象赋值给狗(让狗拥有玩具), 把狗这个对象赋值给人(让人拥有这只狗)

2.4 想要通过人来修改玩具的价格,就需要 person.dog.toy.price 来修改

2.5 person.dog这个值得类型是可选类型 ,因为人的狗属性可能为nil 属性,想要使用person.dog ,必须要强制解包

2.6 person.dog.toy也是可选类型,像这样由可选类型的对象组成的链条就是可选链

3.可选链注意点

3.1 利用可选链赋值的时候一定要解包

3.2 利用可选链取值的时候也不要忘记解包

3.3 利用可选链调用方法的时候 也要先解包

4.利用可选链赋值, 取值,调用方法

4.1 给可选链赋值:

person.dog!.toy!.price = 50太危险 强制解包,如果没值,直接程序崩溃

if let dog = person.dog {
    if let toy = dog.toy {
        toy.price = 50
    }  这样解包虽然安全,但是太麻烦
}

苹果在swift中推荐使用这种方式来给可选链赋值

//当person.dog 为nil的时候,后面的操作就不再执行
person.dog?.toy?.price = 50

4.2 从可选链取值: 从可选链中取出的值得类型一定是可选类型 (有可能取不到)

let price = person.dog?.toy?.price

4.3 可选链调用方法:系统会自动判断可选类型是否有值

person.dog?.toy?.flying()

三.协议

1.如何定义协议

1.1 swift中协议的方式和类,结构体,枚举相似

protocol SomeProtocol {
    // 协议方法
}

1.2 例如:定义一个运动协议

protocol SportProtocol {
    func playBasketball()
    func playFootball()
}

2.声明一个类,并且遵守协议

2.1 声明一个基类(不继承其它类),并遵守协议

class SomeClass:FirstProtocol,AnotherProtocol {
    // 类的内容
    // 实现协议中的方法
}

 例如:
class Person : SportProtocol {
var name : String = ""

func playBasketball() {
    print("打篮球")
}

func playFootball() {
    print("踢足球")
}
}

2.2 类继承自其他类,并遵守协议

class SomeClass:SomeSuperClass, FirstProtocol,AnotherProtocol {
// 类的内容
// 实现协议中的方法
}

3.OC swift不支持多继承, 但是可以通过协议,间接实现多继承

4.协议的继承关系

4.1 swift中的及协议和OC(NSObject)中的不同 是:NSObjectProtocol

protocol CrazySportProtocol : NSObjectProtocol {
    func jumping()
}

4.2 一个协议,可以遵守另一个协议

protocol SportProtocol : CrazySportProtocol {
    func playBasketball()
}

当一个类遵守了这个协议(SportProtocol) 相当于也遵守了CrazySportProtocol协议, 所以必须实现这两个协议中的方法

5.协议的可选性

5.1 OC中协议可以定义为可选和必选,默认是必选的

5.2 默认情况下,swift中的协议都是必须实现的 ,否则编译器会报错

5.3 在swift中如何让协议成为可选的(不用必须实现)

要在协议前加 @objc ,可以保留OC某些特性,在方法前加optional 该方法就是可选的了

      在实现协议方法时,在方法前面也要加@objc
@objc protocol SportProtocol {
    func playBasketball()
    func playFootball()
  //加optional该方法就成为可选的了
    optional func jumping()
}

class Person: SportProtocol {
    @objc func playBasketball() {  在方法前也要加上关键字@objc,不管是可选还是必选
    }
    @objc func playFootball() {
    }
    @objc func jumping() {
    }
}

6.协议在代理模式中的使用

6.1 一般来说协议都用weak来修饰(弱引用)

6.2 weak只能用来修饰类

6.3 在swift中协议既可以被类遵守,也可以被结构体,枚举遵守

6.4 如何让协议只能被类准守

在协议名称后面加上 :class 即可

四.闭包

1.什么是闭包?

闭包和OC中的block非常相似,一般都用来函数的回调

2.block的回顾

 block作为属性的格式: @property (nonatomic, strong) void(^finishedCallback)(NSString *);
 block作为参数的定义格式: (void (^)(NSString * str))finishedCallback

3.闭包的格式:

(参数列表) -> (返回值类型)

4.闭包的使用

闭包的使用
Paste_Image.png

5.尾随闭包

// 尾随闭包 : 如果函数的最后一个参数是一个闭包.那么可以将函数调用写成尾随闭包
//就是把闭包写到()的后面, 本来是写在()里面的
tools?.loadData() { (result) in
    print("在ViewController中获取到数据:\(result)")
}

// 如果函数有且只有一个参数,并且是一个闭包, 那么()也可以省略
tools?.loadData { (result) in
    print("在ViewController中获取到数据:\(result)")
}

6.闭包的循环引用

6.1 一般在定义工具类的时候,会在工具类的方法中用到闭包

6.2 当工具类对闭包有强引用,一个控制器又调用包含该闭包的方法,在闭包方法中使用控制器的属性,就会发生循环引用

6.3 控制器调用方法,就会对工具类有一个强引用, 闭包又拿到控制器的属性,闭包对象就对控制器有一个强引用

6.4 在内存中就相当于这种表现


Paste_Image.png

7.怎么解决闭包的循环引用

与oc中类型,只需要把闭包对控制器的引用改为弱引用

8.怎么改?

当闭包修改控制器的属性时,拿到控制器的属性时,把self(控制器)改成weakself即可

weak var weakself : ViewController? = self
Paste_Image.png

五.swift项目的目录结构简介

1.swift项目目录中没有.h和.m的文件, 只有一个.swift的文件,相当于

2.swift目录中.swift文件就相当于oc中的.h和.m文件

3.在swift中,调用项目中的其他源文件不需要导入头文件 (一个 .swift文件就是一个源文件)

Paste_Image.png

六.懒加载

1.懒加载的介绍

1.1 和OC中不同,swift有专门的关键字实现懒加载

1.2 懒加载本质:当第一次使用时再加载,而且只会被加载一次

2.swift中用lazy关键字来实现懒加载

2.1 懒加载格式

lazy var 变量: 类型 = { 创建变量代码 }()

= 后面是一个闭包 苹果推荐用闭包来实现懒加载,可在闭包中对变量属性进行初始化

2.2 懒加载的使用

lazy var names : [String] = {
    return ["why", "yz", "lmj"]
}()

当执行到上面代码的时候,names不会被加载到内存中, 当names第一次使用时,才会被加载

无论names使用多少次,只会被加载一次,也就是说内存中只有一个names属性地址

七.swift中的常见注释

1.单行注释

和OC中的单行注释一样 使用 // 注释内容

2.多行注释

和OC中的多行注释格式一样 /* 注释内容 */
不同的是,swift中多行注释可以嵌套使用

3.文档注释

与oc中不一样 , swift中 用 /// 注释内容 来实现文档注释

4.分组注释

和oc不一样 oc: #pragma mark - 注释内容
swift: //MARK : - 注释内容

八.访问权限

1.internal :内部的

1.1 当不指定具体的访问权限时,默认为internal

1.2 internal的访问权限: 在当前项目(包)的任何地方都能访问

2.private : 私有的

private的访问权限: 在当前源文件中能够访问 一个 .swift文件就是一个源文件

3.public :公共的

3.1 public的访问权限 : 可以跨包访问

3.2 包的概念: 就是一个项目或一个框架 UIKit也是一个框架

九.异常处理

1.在swift中,如果一个方法的最后有一个throws,那么这个方法能抛出异常

 正则表达式就能抛出异常:
NSRegularExpression(pattern: <#T##String#>, options: <#T##NSRegularExpressionOptions#>)
Paste_Image.png

2.如果一个方法抛出异常,必须要对异常进行处理,否则编译报错

3.异常处理的三种方式

3.1 try : 手动处理异常,可以拿到异常(error)

要在方法前面加上try 而且外面要用do 包装

try方式 --> 手动处理异常, 并且可以获取到最终的异常结果
do {    如果有异常error有值
let regex = try NSRegularExpression(pattern: "", options: .CaseInsensitive)
    } catch {     通过error拿到异常结果
       print(error)
}

3.2 try? : 系统处理异常

try?方式 : 如果有异常,则返回nil,如果没有异常,则返回结果   结果(regex)为可选类型
let regex = try? NSRegularExpression(pattern: "", options: .CaseInsensitive)
regex?.matchesInString("", options: [], range: NSMakeRange(0, 0))

3.3 try! :告诉系统不可能有异常

try!方式(不推荐)  注意:一旦发生异常,程序就会崩溃
let regex = try! NSRegularExpression(pattern: "", options: .CaseInsensitive)

十.如何抛出异常

1.在方法参数的后面加上 throws ,一定要有返回值

2.在某些具体的情况下抛出异常

比如:传的参数不对等等 ,内部要对参数进行判断

3.抛出的异常,一般定义为枚举类型 枚举后面要跟上 ErrorType 这种类型

Paste_Image.png
Paste_Image.png

十一.OC和swift相互调用

1.swift中调用oc

1.1 创建一个桥接文件 (.h的文件) 文件名一般为 Bridge.h

1.2 在桥接文件中导入oc的头文件

1.3 配置桥接文件 工程 —> BuildSetting —> 搜索bridging 在后面写入Bridge.h 的相对路径

Paste_Image.png

2.oc中调用swift

2.1 项目名称要规范 (不能有中文和特殊字符)

2.2 swift中的类,属性,方法名 前面要加 public

2.3 在oc文件中导入 工程名-Swift.h 的头文件 工程名-Swift.h 系统会自动生成

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

推荐阅读更多精彩内容