Swift 泛型 Swift 提供了泛型让你写出灵活且可重用的函数和类型。 Swift 标准库是通过泛型代码构建出来的。 Swift 的数组和字典类型都是泛型集。 你可以创建一个Int数组,也可创建一个String数组,或者甚至于可以是任何其他 Swift 的类型数据数组。 以下实例是一个非泛型函数 exchange 用来交换两个 Int 值: 实例 // 定义一个交换两个变量的函数 func swapTwoInts(_ a: inout Int, _ b: inout Int) { let temporaryA = a a = b b = temporaryA } var numb1 = 100 var…
Tag: iOS
Swift 协议 协议规定了用来实现某一特定功能所必需的方法和属性。 任意能够满足协议要求的类型被称为遵循(conform)这个协议。 类,结构体或枚举类型都可以遵循协议,并提供具体实现来完成协议定义的方法和功能。 语法 协议的语法格式如下: protocol SomeProtocol { // 协议内容 } 要使类遵循某个协议,需要在类型名称后加上协议名称,中间以冒号:分隔,作为类型定义的一部分。遵循多个协议时,各协议之间用逗号,分隔。 struct SomeStructure: FirstProtocol, AnotherProtocol { // 结构体内容 } 如果类在遵循协议的同时拥有父类,应该将父类名放在协议名之前,以逗号分隔。 class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol { // 类的内容 } 对属性的规定 协议用于指定特定的实例属性或类属性,而不用指定是存储型属性或计算型属性。此外还必须指明是只读的还是可读可写的。 协议中的通常用var来声明变量属性,在类型声明后加上{ set get }来表示属性是可读可写的,只读属性则用{ get }来表示。 protocol classa { var marks:…
Swift 扩展 扩展就是向一个已有的类、结构体或枚举类型添加新功能。 扩展可以对一个类型添加新的功能,但是不能重写已有的功能。 Swift 中的扩展可以: 添加计算型属性和计算型静态属性 定义实例方法和类型方法 提供新的构造器 定义下标 定义和使用新的嵌套类型 使一个已有类型符合某个协议 语法 扩展声明使用关键字 extension: extension SomeType { // 加到SomeType的新功能写到这里 } 一个扩展可以扩展一个已有类型,使其能够适配一个或多个协议,语法格式如下: extension SomeType: SomeProtocol, AnotherProctocol { // 协议实现写到这里 } 计算型属性 扩展可以向已有类型添加计算型实例属性和计算型类型属性。 实例 下面的例子向 Int 类型添加了 5 个计算型实例属性并扩展其功能: extension Int { var add: Int {return…
Swift 类型转换 Swift 语言类型转换可以判断实例的类型。也可以用于检测实例类型是否属于其父类或者子类的实例。 Swift 中类型转换使用 is 和 as 操作符实现,is 用于检测值的类型,as 用于转换类型。 类型转换也可以用来检查一个类是否实现了某个协议。 定义一个类层次 以下定义了三个类:Subjects、Chemistry、Maths,Chemistry 和 Maths 继承了 Subjects。 代码如下: class Subjects { var physics: String init(physics: String) { self.physics = physics } } class Chemistry: Subjects { var equations: String init(physics: String, equations: String)…
Swift 可选链 可选链(Optional Chaining)是一种可以请求和调用属性、方法和子脚本的过程,用于请求或调用的目标可能为nil。 可选链返回两个值: 如果目标有值,调用就会成功,返回该值 如果目标为nil,调用将返回nil 多次请求或调用可以被链接成一个链,如果任意一个节点为nil将导致整条链失效。 可选链可替代强制解析 通过在属性、方法、或下标脚本的可选值后面放一个问号(?),即可定义一个可选链。 可选链 ‘?’ 感叹号(!)强制展开方法,属性,下标脚本可选链 ? 放置于可选值后来调用方法,属性,下标脚本 ! 放置于可选值后来调用方法,属性,下标脚本来强制展开值 当可选为 nil 输出比较友好的错误信息 当可选为 nil 时强制展开执行错误 使用感叹号(!)可选链实例 class Person { var residence: Residence? } class Residence { var numberOfRooms = 1 } let john = Person() //将导致运行时错误 let…
Swift 自动引用计数(ARC) Swift 使用自动引用计数(ARC)这一机制来跟踪和管理应用程序的内存 通常情况下我们不需要去手动释放内存,因为 ARC 会在类的实例不再被使用时,自动释放其占用的内存。 但在有些时候我们还是需要在代码中实现内存管理。 ARC 功能 当每次使用 init() 方法创建一个类的新的实例的时候,ARC 会分配一大块内存用来储存实例的信息。 内存中会包含实例的类型信息,以及这个实例所有相关属性的值。 当实例不再被使用时,ARC 释放实例所占用的内存,并让释放的内存能挪作他用。 为了确保使用中的实例不会被销毁,ARC 会跟踪和计算每一个实例正在被多少属性,常量和变量所引用。 实例赋值给属性、常量或变量,它们都会创建此实例的强引用,只要强引用还在,实例是不允许被销毁的。 ARC 实例 class Person { let name: String init(name: String) { self.name = name print(“\(name) 开始初始化”) } deinit { print(“\(name) 被析构”) } } // 值会被自动初始化为nil,目前还不会引用到Person类的实例…
Swift 析构过程 在一个类的实例被释放之前,析构函数被立即调用。用关键字deinit来标示析构函数,类似于初始化函数用init来标示。析构函数只适用于类类型。 析构过程原理 Swift 会自动释放不再需要的实例以释放资源。 Swift 通过自动引用计数(ARC)处理实例的内存管理。 通常当你的实例被释放时不需要手动地去清理。但是,当使用自己的资源时,你可能需要进行一些额外的清理。 例如,如果创建了一个自定义的类来打开一个文件,并写入一些数据,你可能需要在类实例被释放之前关闭该文件。 语法 在类的定义中,每个类最多只能有一个析构函数。析构函数不带任何参数,在写法上不带括号: deinit { // 执行析构过程 } 实例 var counter = 0; // 引用计数器 class BaseClass { init() { counter += 1; } deinit { counter -= 1; } } var show: BaseClass? = BaseClass()…
Swift 构造过程 构造过程是为了使用某个类、结构体或枚举类型的实例而进行的准备过程。这个过程包含了为实例中的每个属性设置初始值和为其执行必要的准备和初始化任务。 Swift 构造函数使用 init() 方法。 与 Objective-C 中的构造器不同,Swift 的构造器无需返回值,它们的主要任务是保证新实例在第一次使用前完成正确的初始化。 类实例也可以通过定义析构器(deinitializer)在类实例释放之前执行清理内存的工作。 存储型属性的初始赋值 类和结构体在实例创建时,必须为所有存储型属性设置合适的初始值。 存储属性在构造器中赋值时,它们的值是被直接设置的,不会触发任何属性观测器。 存储属性在构造器中赋值流程: 创建初始值。 在属性定义中指定默认属性值。 初始化实例,并调用 init() 方法。 构造器 构造器在创建某特定类型的新实例时调用。它的最简形式类似于一个不带任何参数的实例方法,以关键字init命名。 语法 init() { // 实例化后执行的代码 } 实例 以下结构体定义了一个不带参数的构造器 init,并在里面将存储型属性 length 和 breadth 的值初始化为 6 和 12: struct rectangle { var length: Double…
Swift 继承 继承我们可以理解为一个类获取了另外一个类的方法和属性。 当一个类继承其它类时,继承类叫子类,被继承类叫超类(或父类) 在 Swift 中,类可以调用和访问超类的方法,属性和下标脚本,并且可以重写它们。 我们也可以为类中继承来的属性添加属性观察器。 基类 没有继承其它类的类,称之为基类(Base Class)。 以下实例中我们定义了基类 StudDetails ,描述了学生(stname)及其各科成绩的分数(mark1、mark2、mark3): class StudDetails { var stname: String! var mark1: Int! var mark2: Int! var mark3: Int! init(stname: String, mark1: Int, mark2: Int, mark3: Int) { self.stname = stname self.mark1 = mark1 self.mark2…
Swift 下标脚本 下标脚本 可以定义在类(Class)、结构体(structure)和枚举(enumeration)这些目标中,可以认为是访问对象、集合或序列的快捷方式,不需要再调用实例的特定的赋值和访问方法。 举例来说,用下标脚本访问一个数组(Array)实例中的元素可以这样写 someArray[index] ,访问字典(Dictionary)实例中的元素可以这样写 someDictionary[key]。 对于同一个目标可以定义多个下标脚本,通过索引值类型的不同来进行重载,而且索引值的个数可以是多个。 下标脚本语法及应用 语法 下标脚本允许你通过在实例后面的方括号中传入一个或者多个的索引值来对实例进行访问和赋值。 语法类似于实例方法和计算型属性的混合。 与定义实例方法类似,定义下标脚本使用subscript关键字,显式声明入参(一个或多个)和返回类型。 与实例方法不同的是下标脚本可以设定为读写或只读。这种方式又有点像计算型属性的getter和setter: subscript(index: Int) -> Int { get { // 用于下标脚本值的声明 } set(newValue) { // 执行赋值操作 } } 实例 1 import Cocoa struct subexample { let decrementer: Int subscript(index: Int) -> Int…


