swift 知识点记录

Swift 中文文档:https://swift.bootcss.com

1、Swift 中的 nil 和Objective-C 中的 nil 不同
Swift 中的 nil 和Objective-C 中的 nil 不同,在 Objective-C 中 nil 是一个指向不存在对象的指针。在 Swift中, nil 不是指针,他是值缺失的一种特殊类型,任何类型的可选项都可以设置成 nil 而不仅仅是对象类型。

2、标识符的问题
class 不是合法的标识符,但可以使用 class。反引号不属于标识符的一部分。
default 不是合法的标识符,但可以使用 default
class和default是关键字,不可以用关键字做标识符

图片.png
图片.png

3、复合类型
复合型类型是没有名字的类型,它由 Swift 本身定义。Swift 存在两种复合型类型:函数类型和元组类型。元组可以存放多个不同类型的元素。

4、Self 类型不是具体的类型
Self 类型不是具体的类型,而是让你更方便的引用当前类型,不需要重复或者知道该类的名字。

a、在协议声明或者协议成员声明时,Self 类型引用的是最终遵循该协议的类型。
b、在结构体,类或者枚举值声明时,Self 类型引用的是声明的类型。在某个类型成员声明时,Self 类型引用的是该类型。

self(小写) 表达式是对当前类型或者当前实例的显式引用

5、Try 运算符

try 表达式由 try 运算符加上紧随其后的可抛出错误的表达式组成,形式如下:

try 表达式

try 表达式的返回值是该表达式的值。

可选 try 表达式由 try? 运算符加上紧随其后的可抛出错误的表达式组成,形式如下:

try? 表达式

如果表达式没有抛出错误,可选 try 表达式的返回值是可选的该表达式的值,否则,返回值为 nil。

强制 try 表达式由 try! 运算符加上紧随其后的可抛出错误的表达式组成,形式如下:

try! 表达式

强制 try 表达式的返回值是该表达式的值。如果该表达式抛出了错误,将会引发运行时错误

6、闭包
a、一个闭包是否逃逸与其使用时的上下文相关。一个会被立即调用或者作为函数的非逃逸参数传递的闭包表达式是非逃逸的,否则,这个闭包表达式是逃逸的
b、默认情况下,闭包会捕获附近作用域中的常量和变量,并使用强引用指向它们

7、## 捕获列表

默认情况下,闭包会捕获附近作用域中的常量和变量,并使用强引用指向它们。你可以通过一个捕获列表来显式指定它的捕获行为。

捕获列表在参数列表之前,由中括号括起来,里面是由逗号分隔的一系列表达式。一旦使用了捕获列表,就必须使用 in 关键字,即使省略了参数名、参数类型和返回类型。

捕获列表中的项会在闭包创建时被初始化。每一项都会用闭包附近作用域中的同名常量或者变量的值初始化。例如下面的代码示例中,捕获列表包含 a 而不包含 b,这将导致这两个变量具有不同的行为。

var a = 0var b = 0let closure = { [a] in    print(a, b)}a = 10b = 10closure()// 打印“0 10”

在示例中,变量 b 只有一个,然而,变量 a 有两个,一个在闭包外,一个在闭包内。闭包内的变量 a 会在闭包创建时用闭包外的变量 a 的值来初始化,除此之外它们并无其他联系。这意味着在闭包创建后,改变某个 a 的值都不会对另一个 a 的值造成任何影响。与此相反,闭包内外都是同一个变量 b,因此在闭包外改变其值,闭包内的值也会受影响。

如果闭包捕获的值具有引用语义则有所不同。例如,下面示例中,有两个变量 x,一个在闭包外,一个在闭包内,由于它们的值是引用语义,虽然这是两个不同的变量,它们却都引用着同一实例。

class SimpleClass {    var value: Int = 0}var x = SimpleClass()var y = SimpleClass()let closure = { [x] in    print(x.value, y.value)}x.value = 10y.value = 10closure()// 打印“10 10”

如果捕获列表中的值是类类型,你可以使用 weak 或者 unowned 来修饰它,闭包会分别用弱引用和无主引用来捕获该值。

myFunction { print(self.title) }                    // 隐式强引用捕获myFunction { [self] in print(self.title) }             // 显式强引用捕获myFunction { [weak self] in print(self!.title) }   // 弱引用捕获myFunction { [unowned self] in print(self.title) } // 无主引用捕获

在捕获列表中,也可以将任意表达式的值绑定到一个常量上。该表达式会在闭包被创建时进行求值,闭包会按照指定的引用类型来捕获表达式的值。例如:

// 以弱引用捕获 self.parent 并赋值给 parentmyFunction { [weak parent = self.parent] in print(parent!.title) }

关于闭包表达式的更多信息和例子,请参阅 闭包表达式。关于捕获列表的更多信息和例子,请参阅 解决闭包引起的循环强引用

8、guard

Guard 语句

如果一个或者多个条件不成立,可用 guard 语句来退出当前作用域。

guard 语句的格式如下:

guard condition else {    statements}

guard 语句中条件的结果必须是 Bool 类型或者 Bool 的桥接类型。另外,条件也可以是一条可选绑定,请参阅 可选绑定

guard 语句中进行可选绑定的任何常量或者变量,其可用范围从声明开始直到作用域结束。

guard 语句必须有 else 子句,而且必须在该子句中调用返回类型是 Never 的函数,或者使用下面的语句退出当前作用域:

  • return
  • break
  • continue
  • throw

关于控制转移语句,请参阅 控制转移语句。关于 Never 返回类型的函数,请参阅 永不返回的函数

guard 语句语法

guard-statement

guard 语句guard 条件子句 else 代码块

9、计算型属性
setter 子句是可选的,getter 子句是必须的
使用如下形式声明一个计算型变量或计算型属性:

var 变量名称: 类型 {
get {
语句
}
set(setter 名称) {
语句
}
}

10、dynamic
dynamic 修饰符的类成员会由 Objective-C 运行时系统进行动态派发,所以它们会被隐式标记 objc 特性

11、nonobjc
nonobjc 特性告诉编译器该声明不能在 Objective-C 代码中使用,即便它能在 Objective-C 中表示。

12、objcMembers
在Swift中,继承自NSObject的类如果有比较多的属性或方法都需要加上@objc的话,会多比较多的代码。那么可以利用@objcMembers减少代码。被@objcMembers修饰的类,会默认为类、子类、类扩展和子类扩展的所有属性和方法都加上@objc。当然如果想让某一个扩展关闭@objc,则可以用@nonobjc进行修饰

13、输入输出参数 inout
函数参数默认是常量。试图在函数体中更改参数值将会导致编译错误。这意味着你不能错误地更改参数值。如果你想要一个函数可以修改参数的值,并且想要在这些修改在函数调用结束后仍然存在,那么就应该把这个参数定义为输入输出参数(In-Out Parameters)

定义一个输入输出参数时,在参数定义前加 inout 关键字。一个 输入输出参数有传入函数的值,这个值被函数修改,然后被传出函数,替换原来的值。想获取更多的关于输入输出参数的细节和相关的编译器优化,请查看 输入输出参数 一节。

你只能传递变量给输入输出参数。你不能传入常量或者字面量,因为这些量是不能被修改的。当传入的参数作为输入输出参数时,需要在参数名前加 & 符,表示这个值可以被函数修改。

注意

输入输出参数不能有默认值,而且可变参数不能用 inout 标记。

下例中,swapTwoInts(_:_:) 函数有两个分别叫做 ab 的输入输出参数:

func swapTwoInts(_ a: inout Int, _ b: inout Int) {    let temporaryA = a    a = b    b = temporaryA}

swapTwoInts(_:_:) 函数简单地交换 ab 的值。该函数先将 a 的值存到一个临时常量 temporaryA 中,然后将 b 的值赋给 a,最后将 temporaryA 赋值给 b

13、逃逸闭包
将一个闭包标记为 @escaping 意味着你必须在闭包中显式地引用 self

14、恒等运算符

因为类是引用类型,所以多个常量和变量可能在幕后同时引用同一个类实例。(对于结构体和枚举来说,这并不成立。因为它们作为值类型,在被赋予到常量、变量或者传递到函数时,其值总是会被拷贝。)

判定两个常量或者变量是否引用同一个类实例有时很有用。为了达到这个目的,Swift 提供了两个恒等运算符:

相同(===)
不相同(!==)

使用这两个运算符检测两个常量或者变量是否引用了同一个实例:

if tenEighty === alsoTenEighty {
print("tenEighty and alsoTenEighty refer to the same VideoMode instance.")
}
// 打印 "tenEighty and alsoTenEighty refer to the same VideoMode instance."

请注意,“相同”(用三个等号表示,===)与“等于”(用两个等号表示,==)的不同。“相同”表示两个类类型(class type)的常量或者变量引用同一个类实例。“等于”表示两个实例的值“相等”或“等价”,判定时要遵照设计者定义的评判标准。

15、Swift 下标 subscript

下标可以定义在类、结构体和枚举中,是访问集合、列表或序列中元素的快捷方式。可以使用下标的索引,设置和获取值,而不需要再调用对应的存取方法。举例来说,用下标访问一个 Array 实例中的元素可以写作 someArray[index],访问 Dictionary 实例中的元素可以写作 someDictionary[key]。

16、类类型的构造器代理 convenience

为了简化指定构造器和便利构造器之间的调用关系,Swift 构造器之间的代理调用遵循以下三条规则:
规则 1

指定构造器必须调用其直接父类的的指定构造器。

规则 2

便利构造器必须调用同类中定义的其它构造器。

规则 3
便利构造器最后必须调用指定构造器。

17、try try? try! 的区别

try 出现异常处理异常
try? 不处理异常,返回一个可选值类型,出现异常返回nil
try! 不让异常继续传播,一旦出现异常程序停止,类似NSAssert()

18、throws 和 rethrows 的用法与作用
throws 用在函数上, 表示这个函数会抛出错误.
rethrows 与 throws 类似, 不过只适用于参数中有函数, 且函数会抛出异常的情况, rethrows 可以用 throws 替换, 反过来不行

func processNumber(a: Double, b: Double, function: (Double, Double) throws -> Double) rethrows -> Double {
return try function(a, b)
}

19、associatedtype 的作用
简单来说就是 protocol 使用的泛型
例如定义一个列表协议
protocol ListProtcol {
associatedtype Element
func push(_ element:Element)
func pop(_ element:Element) -> Element?
}

实现协议的时候, 可以使用 typealias 指定为特定的类型, 也可以自动推断, 如
class IntList: ListProtcol {
typealias Element = Int // 使用 typealias 指定为 Int
var list = Element
func push(_ element: Element) {
self.list.append(element)
}
func pop(_ element: Element) -> Element? {
return self.list.popLast()
}
}
class DoubleList: ListProtcol {
var list = Double
func push(_ element: Double) {// 自动推断
self.list.append(element)
}
func pop(_ element: Double) -> Double? {
return self.list.popLast()
}
}

20、weak 和 unowned 应用场合

  • weak

一般使用在两个对象满足其生命周期没有太大关系之间。例如viewController和delegate等,它们的生命周期不是包含关系,而是互相平行的。

  • unowned

一般使用在两个对象满足其中一个对象的生命周期包含另一个对象的生命周期。例如一个viewController中的timer的生命周期会被包含在viewController生命周期内,所以timer中的Block对self(viewController)的引用就使用unowned。

21、[高阶函数map、flatMap、CompactMap 、filter 、reduce的区别?

https://juejin.cn/post/6983973263508504583

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