分类:Phone / IOS / Objective-C / Swift

Swift中文教程(九) 类与结构

类与结构是编程人员在代码中会经常用到的代码块。在类与结构中可以像定义常量,变量和函数一样,定义相关的属性和方法以此来实现各种功能。   和其它的编程语言不太相同的是,Swift不需要单独创建接口或者实现文件来使用类或者结构。Swift中的类或者结构可以在单文件中直接定义,一旦定义完成后,就能够被直接其它代码使用。   注意:一个类的实例一般被视作一个对象,但是在Swift中,类与结构更像是一个函数方法,在后续的章节中更多地是讲述类和结构的功能性。   1、类和结构的异同 类和结构有一些相似的地方,它们都可以: 定义一些可以赋值的属性; 定义具有功能性的方法 定义下标,使用下标语法 定义初始化方法来设置初始状态 在原实现方法上的可扩展性 根据协议提供某一特定类别的基本功能 更多内容可以阅读:属性,方法,下标,初始化,扩展和协议等章节 类还有一些结构不具备的特性: 类的继承性 对类实例实时的类型转换 析构一个类的实例使之释放空间 引用计数,一个类实例可以有多个引用… Read More

Swift中文教程(十七) 可选链

可选链(Optional Chaining)是一种可以请求和调用属性、方法及子脚本的过程,它的自判断性体现于请求或调用的目标当前可能为空(nil)。如果自判断的目标有值,那么调用就会成功;相反,如果选择的目标为空(nil),则这种调用将返回空(nil)。多次请求或调用可以被链接在一起形成一个链,如果任何一个节点为空(nil)将导致整个链失效。   注意: Swift 的自判断链和 Objective-C 中的消息为空有些相像,但是 Swift 可以使用在任意类型中,并且失败与否可以被检测到。   可选链可替代强制解析   通过在想调用的属性、方法、或子脚本的可选值(optional value)(非空)后面放一个问号,可以定义一个可选链。这一点很像在可选值后面放一个声明符号来强制拆得其封包内的值。他们的主要的区别在于当可选值为空时可选链即刻失败,然而一般的强制解析将会引发运行时错误。   为了反映可选链可以调用空(nil),不论你调用的属性、方法、子脚本等返回的值是不是可选值,它的返回结果都是一个可选值。你可以利用这个返回值来检测你的可选链是否调用成功,有返回值即成功,返回nil则失败。   调用可选链的返回结果与原本的返回结果具有相同的类型,但是原本的返回结果被包装成了一个可选值,当可选链调用成功时,一个应该返回Int的属性将会返回Int?。  … Read More

Swift中文教程(十六) 自动引用计数

Swift使用自动引用计数(ARC)来管理应用程序的内存使用。这表示内存管理已经是Swift的一部分,在大多数情况下,你并不需要考虑内存的管理。当实例并不再被需要时,ARC会自动释放这些实例所使用的内存。   但是,少数情况下,你必须提供部分代码的额外信息给ARC,这样它才能够帮你管理这部分内存。本章阐述了这些情况并且展示如何使用ARC来管理应用程序的内存。   注意 引用计数仅仅作用于类实例上。结构和枚举是值类型,而非引用类型,所以不能被引用存储和传递。   1、ARC怎样工作 每当你创建一个类的实例,ARC分配一个内存块来存储这个实例的信息,包含了类型信息和实例的属性值信息。   另外当实例不再被使用时,ARC会释放实例所占用的内存,这些内存可以再次被使用。   但是,如果ARC释放了正在被使用的实例,就不能再访问实例属性,或者调用实例的方法了。直接访问这个实例可能造成应用程序的崩溃。   为了保证需要实例时实例是存在的,ARC对每个类实例,都追踪有多少属性、常量、变量指向这些实例。当有活动引用指向它时,ARC是不会释放这个实例的。   为实现这点,当你将类实例赋值给属性、常量或变量时,指向实例的一个强引用(strong reference)将会被构造出来。被称为强引用是因为它稳定地持有这个实例,当这个强引用存在是,实例就不能够被释放。   2、ARC实例… Read More

Swift中文教程(十五) 析构

在一个类的实例被释放之前,析构函数会被调用。用关键字deinit来定义析构函数,类似于初始化函数用init来定义。析构函数只适用于class类型。   1、析构过程原理 Swift 会自动释放不再需要的实例以释放资源。如自动引用计数那一章描述,Swift 通过自动引用计数(ARC)处理实例的内存管理。通常当你的实例被释放时不需要手动地去清理。但是,当使用自己的资源时,你可能需要进行一些额外的清理。 例如,如果创建了一个自定义的类来打开一个文件,并写入一些数据,你可能需要在类实例被释放之前关闭该文件。   在类的定义中,每个类最多只能有一个析构函数。析构函数不带任何参数,在写法上不带括号: Java代码 deinit { // 执行析构过程 } 析构函数是在实例释放发生前一步被自动调用。不允许主动调用自己的析构函数。子类继承了父类的析构函数,并且在子类析构函数实现的最后,父类的析构函数被自动调用。即使子类没有提供自己的析构函数,父类的析构函数也总是被调用。     因为直到实例的析构函数被调用时,实例才会被释放,所以析构函数可以访问所有请求实例的属性,并且根据那些属性可以修改它的行为(比如查找一个需要被关闭的文件的名称)。  … Read More

Swift中文教程(十四) 初始化

初始化是类,结构体和枚举类型实例化的准备阶段。这个阶段设置这个实例存储的属性的初始化数值和做一些使用实例之前的准备以及必须要做的其他一些设置工作。   通过定义构造器(initializers)实现这个实例化过程,也就是创建一个新的具体实例的特殊方法。和Objective-C不一样的是,Swift的构造器没有返回值。它们主要充当的角色是确保这个实例在使用之前能正确的初始化。   类实例也能实现一个析构器(deinitializer),在类实例销毁之前做一些清理工作。更多的关于析构器(deinitializer)的内容可以参考Deinitialization。     1、存储属性的初始化 类和结构体必须在它们被创建时把它们所有的属性设置为合理的值。存储属性不能为不确定状态   你可以在构造方法里面给一个属性设置一个初始值,或者在定义的时候给属性设置一个默认值,这个行为将会在接下来的章节描述。 注意:当你对给一个属性分配一个默认值的时候,它会调用它相对应的初始化方法,这个值是对属性直接设置的,不会通知它对应的观察者   构造器 构造器是创建一个具体类型实例的方法。最简单的构造器就是一个没有任何参数实例方法,写作init。   在下面的例子定义了一个叫Fahrenheit(华氏度)的新结构体,来储存转换成华氏度的温度。Fahrenheit结构体,有一个属性,叫temperature(温度),它的类型为Double(双精度浮点数): Java代码 struct Fahrenheit… Read More

Swift中文教程(十三) 继承

一个类可以从另外一个类中继承方法,属性或者其它的一些特性。当一个类继承于另外一个类时,这个继承的类叫子类,被继承的类叫父类。继承是Swift中类区别于其它类型的一个基本特征。   Swift中的类可以调用父类的方法,使用父类的属性和下标,还可以根据需要使用重写方法或者属性来重新定义和修改他们的一些特性。Swift可以帮助你检查重写的方法和父类的方法定义是相符的。   类还可以为它继承的属性添加观察者,这样可以能够让它在一个属性变化的时候得到通知。属性观察者可以被添加给任何属性,不管它之前是存储属性还是计算属性。   1、定义一个基类 任何一个不继承于其它类的类被称作基类 注意:Swift的类不是从一个全局基类继承而来。在你编写代码的时,只要是在类的定义中没有继承自父类的类都是基类。   下面的例子定义了一个叫Vehicle的基类。基类包含两个所有交通工具通用的属性numberOfWheels和maxPassengers。这两个属性被一个叫description的方法使用,通过返回一个String描述来作为这个交通工具的特征: C代码 class Vehicle { var numberOfWheels: Int var maxPassengers:… Read More

Swift中文教程(十二) 下标

类,结构和枚举类型都可以通过定义下标来访问一组或者一个序列中的成员元素。通过下标索引就可以方便地检索和设置相应的值,而不需要其他的额外操 作。比如你可以通过someArray[index]来访问数组中的元素,或者someDictionary[key]来对字典进行索引。   你可以为一个类型定义多个下标,以及适当的下标重载用来根据传递给下标的索引来设置相应的值。下标不仅可以定义为一维的,还可以根据需要定义为多维的,多个参数的。   1、下标语法 下标可以让你通过实例名后加中括号内一个或多个数值的形式检索一个元素。语法和方法语法和属性语法类似,通过使用subscript关键定义,一个 或多个输入参数以及一个返回值。不同于实例方法的是,下标可以是可读写的或者只读的。这种行为通过一个getter和setter语句联通,就像是计算属 性一样。 C代码 subscript(index: Int) -> Int {     get {         // return an … Read More

Swift中文教程(十一) 方法

方法是关联到一个特定类型的函数。类、结构、枚举所有可以定义实例方法,封装特定任务和功能处理给定类型的一个实例。类、结构、枚举类型还可以定义方法,相关的类型本身。类型方法类似于objective – c类方法。 结构和枚举可以定义方法swift与C和objective – C是一个重大的区别。在objective – c中,类是唯一类型可以定义方法。在swift,你可以选择是否要定义一个类,结构,或枚举,还有你定义方法类型的灵活性创造。   1、实例方法 实例方法是属于一个特定的类,结构或枚举实例的功能。他们支持这些实例的功能,无论是通过提供方法来访问和修改实例属性,或提供的功能与实例的目的。实例方法具有完全相同的语法功能,如功能描述 你所属的类型的打开和关闭括号内写一个实例方法。一个实例方法具有隐式访问所有其他实例方法和该类型的属性。一个实例方法只能在它所属的类的特定实例调用,它不能访问一个不存在的实例。 这里,定义了一个简单的计数器类,它可以用来计数一个动作发生的次数的示例: C代码 class Counter { var count =… Read More

Swift中文教程(二十一) 协议

Protocol(协议)用于统一方法和属性的名称,而不实现任何功能。协议能够被类,枚举,结构体实现,满足协议要求的类,枚举,结构体被称为协议的遵循者。   遵循者需要提供协议指定的成员,如属性,方法,操作符,下标等。     协议的语法   协议的定义与类,结构体,枚举的定义非常相似,如下所示: C代码 protocol SomeProtocol { // 协议内容 }   在类,结构体,枚举的名称后加上协议名称,中间以冒号:分隔即可实现协议;实现多个协议时,各协议之间用逗号,分隔,如下所示: C代码 struct SomeStructure:… Read More

Swift中文教程(二十二) 泛型

泛型代码可以让你写出根据自我需求定义、适用于任何类型的,灵活且可重用的函数和类型。它的可以让你避免重复的代码,用一种清晰和抽象的方式来表达代码的意图。   泛型是 Swift 强大特征中的其中一个,许多 Swift 标准库是通过泛型代码构建出来的。事实上,泛型的使用贯穿了整本语言手册,只是你没有发现而已。例如,Swift 的数组和字典类型都是泛型集。你可以创建一个Int数组,也可创建一个String数组,或者甚至于可以是任何其他 Swift 的类型数据数组。同样的,你也可以创建存储任何指定类型的字典(dictionary),而且这些类型可以是没有限制的。   泛型所解决的问题   这里是一个标准的,非泛型函数swapTwoInts,用来交换两个Int值: C代码 func swapTwoInts(inout a: Int, inout… Read More

Swift中文教程(二十) 扩展

扩展就是向一个已有的类、结构体或枚举类型添加新功能(functionality)。这包括在没有权限获取原始源代码的情况下扩展类型的能力(即逆向建模)。扩展和 Objective-C 中的分类(categories)类似。(不过与Objective-C不同的是,Swift 的扩展没有名字。)   Swift 中的扩展可以:   添加计算型属性和计算静态属性 定义实例方法和类型方法 提供新的构造器 定义下标 定义和使用新的嵌套类型 使一个已有类型符合某个接口 注意: 如果你定义了一个扩展向一个已有类型添加新功能,那么这个新功能对该类型的所有已有实例中都是可用的,即使它们是在你的这个扩展的前面定义的。   扩展语法(Extension Syntax)  … Read More

Swift中文教程(十九) 类型嵌套

枚举类型常被用于实现特定类或结构体的功能。也能够在有多种变量类型的环境中,方便地定义通用类或结构体来使用,为了实现这种功能,Swift允许你定义类型嵌套,可以在枚举类型、类和结构体中定义支持嵌套的类型。   要在一个类型中嵌套另一个类型,将需要嵌套的类型的定义写在被嵌套类型的区域{}内,而且可以根据需要定义多级嵌套。     类型嵌套实例   下面这个例子定义了一个结构体BlackjackCard(二十一点),用来模拟BlackjackCard中的扑克牌点数。BlackjackCard结构体包含2个嵌套定义的枚举类型Suit 和 Rank。   在BlackjackCard规则中,Ace牌可以表示1或者11,Ace牌的这一特征用一个嵌套在枚举型Rank的结构体Values来表示。 C代码 struct BlackjackCard { // 嵌套定义枚举型Suit enum Suit:… Read More

Swift中文教程(十八) 类型检查

类型检查是一种检查类实例的方式,并且或者也是让实例作为它的父类或者子类的一种方式。   类型检查在 Swift 中使用is 和 as操作符实现。这两个操作符提供了一种简单达意的方式去检查值的类型或者转换它的类型。   你也可以用来检查一个类是否实现了某个协议,就像在 Protocols Checking for Protocol Conformance部分讲述的一样。   定义一个类层次作为例子   你可以将它用在类和子类的层次结构上,检查特定类实例的类型并且转换这个类实例的类型成为这个层次结构中的其他类型。这下面的三个代码段定义了一个类层次和一个包含了几个这些类实例的数组,作为类型检查的例子。   第一个代码片段定义了一个新的基础类MediaItem。这个类为任何出现在数字媒体库的媒体项提供基础功能。特别的,它声明了一个… Read More

Swift中文教程(二十三) 高级运算符

除了基本操作符中所讲的运算符,Swift还有许多复杂的高级运算符,包括了C语和Objective-C中的位运算符和移位运算。   不同于C语言中的数值计算,Swift的数值计算默认是不可溢出的。溢出行为会被捕获并报告为错误。你是故意的?好吧,你可以使用Swift为你准备的另一套默认允许溢出的数值运算符,如可溢出加&+。所有允许溢出的运算符都是以&开始的。   自定义的结构,类和枚举,是否可以使用标准的运算符来定义操作?当然可以!在Swift中,你可以为你创建的所有类型定制运算符的操作。   可定制的运算符并不限于那些预设的运算符,自定义有个性的中置,前置,后置及赋值运算符,当然还有优先级和结合性。这些运算符的实现可以运用预设的运算符,也可以运用之前定制的运算符。   位运算符   位操作符通常在诸如图像处理和创建设备驱动等底层开发中使用,使用它可以单独操作数据结构中原始数据的比特位。在使用一个自定义的协议进行通信的时候,运用位运算符来对原始数据进行编码和解码也是非常有效的。   Swift支持如下所有C语言的位运算符:   按位取反运算符   按位取反运算符~对一个操作数的每一位都取反。   这个运算符是前置的,所以请不加任何空格地写着操作数之前。 let… Read More