Swift学习笔记

96
ilei
2016.02.04 16:40* 字数 2182

如果一个变量之后可能变成nil的话请不要使用隐式解析可选类型。如果你需要在变量的生命周期中判断是否是nil的话,请使用普通可选类型。

1.在对负数b求余时,b的符号会被忽略。这意味着 a % b 和 a % -b的结果是相同的。不同于 C 语言和 Objective-C,Swift 中是可以对浮点数进行求余的。

2.空合运算符(a ?? b)将对可选类型a进行空判断,如果a包含一个值就进行解封,否则就返回一个默认值b.这个运算符有两个条件:

表达式a必须是Optional类型 ;默认值b的类型必须要和a存储值的类型保持一致

空合运算符相当于a != nil ? a! : b

3.String是值类型

注意在 Swift 中,使用可拓展的字符群集作为Character值来连接或改变字符串时,并不一定会更改字符串的字符数量。

使用endIndex属性可以获取最后一个Character的后一个位置的索引。因此,endIndex属性不能作为一个字符串的有效下标。

4.Swift 的所有基本类型(比如String,Int,Double和Bool)默认都是可哈希化的,可以作为集合的值的类型或者字典的键的类型。没有关联值的枚举成员值(在枚举有讲述)默认也是可哈希化的。

5.贯穿(Fallthrough)

6.忽略外部参数名(Omitting External Parameter Names)如果你不想为第二个及后续的参数设置外部参数名,用一个下划线( _ )代替一个明确的参数名

一个函数最多只能有一个可变参数。如果函数有一个或多个带默认值的参数,而且还有一个可变参数,那么把可变参数放在参数表的最后。

输入输出参数调用时加了 & 的前缀。

7.闭包 reversed = names.sort( { s1, s2 in return s1 > s2 } )

单表达式闭包隐式返回 reversed = names.sort( { s1, s2 in s1 > s2 } )

参数名称缩写 reversed = names.sort( { $0 > $1 } )

运算符函数 reversed = names.sort(>)

尾随闭包 reversed = names.sort() { $0 > $1 } 只有一个参数 reversed = names.sort { $0 > $1 }

函数和闭包是引用类型~~~~~

非逃逸闭包(Nonescaping Closures) @noescape 可以隐式地使用self

自动闭包(Autoclosures)用于包装传递给函数作为参数的表达式。

8.枚举

关联值

enum Barcode {  

case UPCA(Int, Int, Int, Int)

case QRCode(String)

}

原始值

enum ASCIIControlCharacter: Character {

case Tab = "\t"

case LineFeed = "\n"

case CarriageReturn = "\r"

}

9.与 Objective-C 语言不同的是,Swift 允许直接设置结构体属性的子属性。

与结构体不同,类实例没有默认的成员逐一构造器。

在 Swift 中,所有的结构体和枚举类型都是值类型。

10.计算属性可以用于类、结构体和枚举,存储属性只能用于类和结构体。

当值类型的实例被声明为常量的时候,它的所有属性也就成了常量。

如果一个被标记为lazy的属性在没有初始化时就同时被多个线程访问,则无法保证该属性只会被初始化一次。(这点岂不很蛋疼。。。)

可以为除了延迟存储属性之外的其他存储属性添加属性观察器,也可以通过重写属性的方式为继承的属性(包括存储属性和计算属性)添加属性观察器。

使用关键字static来定义类型属性。在为类定义计算型类型属性时,可以改用关键字class来支持子类对父类的实现进行重写。

11.在实例方法中修改值类型 mutating (默认情况下,值类型的属性不能在它的实例方法中被修改。)

枚举的可变方法可以把self设置为同一枚举类型中不同的成员:

在方法的func关键字之前加上关键字static,来指定类型方法。类还可以用关键字class来允许子类重写父类的方法实现。

12.你可以将一个继承来的只读属性重写为一个读写属性,只需要在重写版本的属性里提供 getter 和 setter 即可。但是,你不可以将一个继承来的读写属性重写为一个只读属性。

如果你在重写属性中提供了 setter,那么你也一定要提供 getter。如果你不想在重写版本中的 getter 里修改继承来的属性值,你可以直接通过super.someProperty来返回继承来的值,其中someProperty是你要重写的属性的名字。

你不可以为继承来的常量存储型属性或继承来的只读计算型属性添加属性观察器。这些属性的值是不可以被设置的。

通过把方法,属性或下标标记为final来防止它们被重写。通过在关键字class前添加final修饰符(final class)来将整个类标记为 final 的。这样的类是不可被继承的。

13.对于类的实例来说,它的常量属性只能在定义它的类的构造过程中修改;不能在子类中修改。

假如你希望默认构造器、逐一成员构造器以及你自己的自定义构造器都能用来创建实例,可以将自定义的构造器写到扩展(extension)中,而不是写在值类型的原始定义中。

你可以用非可失败构造器重写可失败构造器,但反过来却不行。

如果你使用闭包来初始化属性,请记住在闭包执行时,实例的其它部分都还没有初始化。这意味着你不能在闭包里访问其它属性,即使这些属性有默认值。同样,你也不能使用隐式的self属性,或者调用任何实例方法。

14.对于类的实例来说,它的常量属性只能在定义它的类的构造过程中修改;不能在子类中修改。
如果你为某个值类型定义了一个自定义的构造器,你将无法访问到默认构造器(如果是结构体,还将无法访问逐一成员构造器)。
假如你希望默认构造器、逐一成员构造器以及你自己的自定义构造器都能用来创建实例,可以将自定义的构造器写到扩展(extension)中。
析构器只适用于类类型

15.弱引用(weak reference)和无主引用(unowned reference)

对于生命周期中会变为nil的实例使用弱引用。相反地,对于初始化赋值后再也不会被赋值为nil的实例,使用无主引用。

16.可以使用try?通过将错误转换成一个可选值来处理错误。如果在评估try?表达式时一个错误被抛出,那么表达式的值就是nil。

17.扩展可以添加新的计算型属性,但是不可以添加存储型属性,也不可以为已有属性添加属性观察器。
扩展能为类添加新的便利构造器,但是它们不能为类添加新的指定构造器或析构器。指定构造器和析构器必须总是由原始的类实现来提供。

18.如果协议要求属性是可读可写的,那么该属性不能是常量属性或只读的计算型属性。如果协议只要求属性是只读的,那么该属性不仅可以是只读的,如果代码需要的话,还可以是可写的。
可选协议只能在含有@objc前缀的协议中生效。且@objc的协议只能被类遵循。

19.注意:如果你定义了一个public访问级别的协议,那么实现该协议提供的必要函数也会是public的访问级别。这一点不同于其他类型,比如,public访问级别的其他类型,他们成员的访问级别为internal。

移动开发