Swift
文章平均质量分 89
1024星球
Less is more.
展开
-
Swift系列三十五 - 源码和第三方库
Swift 于 2015 年正式开源。一、目录简介Github:https://github.com/apple/swift几个可能会经常看的目录:docs:一些文档stdlib:Swift 源码lib:C++源码include:C++头文件标准库源码位置:https://github.com/apple/swift/tree/main/stdlib/public/core二、Metadata 分析文档:https://github.com/apple/swift/blob/m原创 2021-05-08 09:38:26 · 630 阅读 · 2 评论 -
Swift系列三十四 - 响应式编程(RxSwift的使用)
响应式编程(Reactive Programming,简称RP)也是一种编程范式,于1997年提出,可以简化异步编程,提供更优雅的数据绑定。一、初始响应式编程响应式编程一般与函数式融合在一起,所以也会叫做:函数响应式编程(Functional Reactive Programming,简称FRP)。比较著名的,成熟的响应式框架:ReactiveCocoa简称RAC,有OC、Swift版本官网:http://reactivecocoa.io/github:https://github.c原创 2021-05-08 09:34:49 · 1262 阅读 · 2 评论 -
Swift系列三十三 - 面向协议编程
面向协议编程(Protocol Oriented Programming,简称POP)是Swift的一种编程范式,Apple于2015年WWDC提出。在Swift的标准库中,能见到大量POP的影子。一、POP和OOP1.1. 回顾OOPSwift也是一门面向对象的编程语言(Object Oriented Programming,简称OOP)。OOP的三大特性:封装、继承、多态。继承的经典使用场景:当多个类(比如A、B、C类)具有很多共性时,可以将这些共性抽取到一个父类中(比如D类),最后A、B、原创 2021-05-08 09:33:53 · 792 阅读 · 0 评论 -
Swift系列三十二 - 函数式编程
函数式编程(Funtional Programming,简称FP)是一种编程范式,也就是如何编写程序的方法论。一、什么是函数式编程?1.1. 介绍主要思想: 把计算过程尽量分解成一系列可复用函数的调用。主要特征: 函数是"一等公民"(函数与其他数据类型一样的地位,可以赋值给其他变量,也可以作为函数参数、函数返回值)。函数式编程中几个常用的概念:Higher-Order Function、Function CurryingFunctor、Applicative Functor、Monad原创 2021-05-08 09:31:29 · 746 阅读 · 1 评论 -
Swift系列三十一 - 多线程
多线程在Swift中也是首先使用GCD。一、异步1.1. GCD开启异步线程示例代码:class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() print("主线程", Thread.current) DispatchQueue.global().async {原创 2021-05-07 09:42:28 · 1287 阅读 · 0 评论 -
Swift系列三十 - 从OC到Swift(二)
协议、关联对象、KVO等Swift和OC的关系。一、协议1.1. 只能被class继承的协议示例代码:protocol Runnable1: AnyObject { }protocol Runnable2: class { }@objc protocol Runnable3 { }被@objc修饰的协议,还可以暴露给OC去遵守实现。1.2. 可选协议正常情况下,Swift定义的协议内容都需要实现,如果需要可选实现,可以定义一个协议扩展,在扩展中空实现需要可选实现的协议。也可以通过@o原创 2021-05-07 09:40:50 · 640 阅读 · 2 评论 -
Swift系列二十九 - 从OC到Swift(一)
现在大部分项目还是纯OC,即使迁移到Swift也只能是一点点模块过度,那么OC和Swift有什么样的区别呢?两者之间怎样相互调用?一、注释// MARK:类似于OC中的#pragma mark// MARK: -类似于OC中的#pragma mark-// TODO:用于标记未完成的任务// FIXME: -用于标记待修复的问题#warning("msg")用来做全局提示示例代码:public class Person { // MARK: - 属性 var age =原创 2021-05-07 09:38:36 · 623 阅读 · 0 评论 -
Swift系列二十八 - 数组
Swift中的数组有一些高级API非常好用(用法类似JavaScript)。一、Array的常见操作基础代码:var arr = [1, 2, 3, 4]print(arr) // 输出:[1, 2, 3, 4]1.1. map(映射)遍历每一个元素,元素在函数(闭包表达式)中处理完成后把返回值放到新的数组,返回一个新数组。示例代码:var arr2 = arr.map { element -> Int in return element * 2}print(a原创 2021-05-06 10:16:32 · 643 阅读 · 0 评论 -
Swift系列二十七 - 字符串
Swift的字符串类型String,跟OC的NSString,在API设计上还是有较大差异的。一、字符串内容操作1.1. 字符串的拼接示例代码:// 空字符串var emptyStr1 = ""var emptyStr2 = String()var str: String = "1"// 拼接str.append("_2")// 重载运算符+str = str + "_3"// 重载运算符+=str += "_4"// \()插值str = "\(str)_5"// 长度原创 2021-05-06 10:15:08 · 524 阅读 · 2 评论 -
Swift系列二十六 - 模式匹配
一、字面量(Literal)了解模式之前,我们先看下什么是字面量。var age = 10var isShow = falsevar name = "Jack"上面代码中的10,false,"Jack"就是字面量。1.1. 字面量类型常见字面量的默认类型:public typealias IntegerLiteralType = Intpublic typealias FloatLiteralType = Doublepublic typealias BooleanLiteralTyp原创 2021-05-06 10:14:05 · 515 阅读 · 1 评论 -
Swift系列二十五 - 内存管理(二)
谈内存必然离不开指针的概念,指针既是难点也是重点。一、指针简介Swift中也有专门的指针类型,这些都被定性为Unsafe(不安全的),常见的有以下4种类型:UnsafePointer<Pointee>:类似于const Pointee *(只读的泛型指针)UnsafeMutablePointer<Pointee>:类似于Pointee *(可读可写的泛型指针)UnsafeRawPointer:类似于const void *(只读的原始类型指针)UnsafeMutabl原创 2021-04-30 09:43:45 · 499 阅读 · 0 评论 -
Swift系列二十四 - 内存管理(一)
和OC一样,Swift也是采取基于引用计数的ARC内存管理方案(针对堆空间)。一、引用介绍Swift的ARC中有3中引用:强引用(strong reference):默认情况下,引用都是强引用弱引用(weak reference):通过weak定义弱引用无主引用(unowned reference):通过unowned定义无主引用1.1. 强引用示例代码:class Person { deinit { print("Person.deinit") }}原创 2021-04-30 09:42:25 · 997 阅读 · 1 评论 -
Swift系列二十三 - 访问控制
在访问权限控制这块,Swift提供了5个不同的访问级别。一、访问控制关键词以下是从高到低排列(实体:被访问级别修饰的内容;模块:本项目或其他第三方库):open:允许在定义实体的模块、其他模块中访问,允许其他模块进行继承、重写(open只能用在类、类成员上)public:允许在定义实体的模块、其他模块中访问,不允许其他模块进行继承、重写internal:只允许在定义实体的模块中访问,不允许在其他模块中访问fileprivate:只允许在定义实体的源文件中访问private:只允许在定义实体原创 2021-04-30 09:39:48 · 268 阅读 · 0 评论 -
Swift系列二十二 - 扩展
Swift中的扩展有点类似于OC中的分类(Category)。扩展(Extension)可以为枚举、结构体、类、协议添加新功能(方法、计算属性、下标、初始化器(类只能扩展便捷初始化器)、嵌套类型、协议等等)。扩展不能做的事情:不能覆盖原有的功能不能添加存储属性、不能向已有的属性添加属性观察器不能添加父类不能添加指定初始化器,不能添加反初始化器……一、结构体1.1. Double为Double添加距离单位:extension Double { var km: Double原创 2021-04-29 09:45:00 · 902 阅读 · 4 评论 -
Swift系列二十一 - 高级运算符
如果对C++有了解的话,理解运算符重载(Operator Overload)就很简单。OC不支持运算符重载,但Swift支持。一、溢出运算符(Overflow Operator)Swift的算数运算符出现溢出时会抛出运行时错误。示例代码一:print(Int8.min) // 输出:-128print(Int8.max) // 输出:127print(UInt8.min) // 输出:0print(UInt8.max) // 输出:255var a = UInt8.maxa += 1原创 2021-04-29 09:43:01 · 349 阅读 · 0 评论 -
Swift系列二十 - String和Array底层分析
String和Array用起来很简单,但底层是如何存储的呢?一、String1.1. 1个String变量占用多少内存?示例代码:var str1 = "0123456789"print(MemoryLayout.size(ofValue: str1))// 输出:16print(Mems.memStr(ofVal: &str1))/* 输出: 0x3736353433323130 0xea00000000003938 */结论: 一个String变量占用16个字节。原创 2021-04-29 09:37:10 · 625 阅读 · 0 评论 -
Swift系列十九 - 泛型
泛型在Java,C++等多个语言中都有,C#把泛型发挥的淋漓尽致,OC中也有泛型(比如OC中的数组,你可以限制他里面装的是NSString类型),Swift中泛型的使用范围更加多元化。一、泛型函数1.1. 泛型可以将类型参数化,提高代码复用率,减少代码量示例代码:var n1 = 10var n2 = 20func swapValues(_ a: inout Int, _ b: inout Int) { (a, b) = (b, a)}swapValues(&n1, &am原创 2021-04-29 09:35:34 · 359 阅读 · 0 评论 -
Swift系列十八 - 错误处理
在很多编程语言中都有异常(Exception)处理,Swift官方使用的是错误(Error)来描述的。但两者定义本质是一样的。一、定义错误开发过程中常见的错误:语法错误(编译报错)逻辑错误运行时错误(可能会导致闪退,一般也叫做异常)……示例代码一:func divide(_ num1: Int, _ num2: Int) -> Int { num1 / num2}print(divide(20, 10))// 输出:2上面示例代码正常运行,但是如果把num2传值原创 2021-04-29 09:33:27 · 497 阅读 · 0 评论 -
Swift系列十七 - 任意类型
任意类型、泛型、强制类型转换在开发中也是经常用到。一、Any、AnyObjectSwift提供了2种特殊的类型:Any,AnyObject。Any: 可以代表任意类型(枚举、结构体、类,也包括函数类型)AnyObject: 可以代表任意类类型(在协议后面写上:AnyObject代表只有类能遵守这个协议)示例代码一:class Person { }var p: Any = 10p = "idbeny"p = Person()如果变量p后面是具体类型或不写类型就不能编译通过。示例代码二原创 2021-04-29 09:31:42 · 749 阅读 · 0 评论 -
Swift系列十六 - 协议
协议在Swift中极其重要,可以说任何项目开发都会用到协议。一、协议(Protocol)的定义协议可以用来定义方法、属性、下标的声明,协议可以被枚举、结构体、类遵守(多个协议之间用逗号隔开)。示例代码:// 定义协议protocol Drawable { var x: Int { get set } var y: Int { get } func draw() subscript(index: Int) -> Int { get set }}protoc原创 2021-04-29 09:29:56 · 690 阅读 · 1 评论 -
Swift系列十五 - 可选链
多个可选类型组合在一起调用就会形成可选链条。一、可选链(Optional Chaining)1.1. 什么是可选链示例代码:class Car { var price = 0 }class Dog { var weight = 0 }class Person { var name: String = "" var dog: Dog = Dog() var car: Car? = Car() func age() -> Int { 30 } func原创 2021-04-28 09:51:37 · 221 阅读 · 0 评论 -
Swift系列十四 - 初始化器
类、结构体、枚举都可以定义初始化器。但是枚举一般很少用来手动定义初始化器。一、初始化器类有2中初始化器:指定初始化器(designated initializer)、便捷初始化器(convenience initializer)。格式:// 指定初始化器init(parameters) { statements}// 便捷初始化器convenience init(parameters) { statements}示例代码一:class Size { var原创 2021-04-28 09:50:51 · 277 阅读 · 0 评论 -
Swift系列十三 - 多态及实现原理
面向对象语言三大特性:封装、继承、多态。在OC中多态是用Runtime实现的,在C++中用虚表实现多态,今天我们了解一下Swift中的多态及其原理(和**C++**类似,都是使用虚表)。什么是多态?父类指针指向子类对象就是多态。一、结构体和类函数调用比较1.1. 结构体通过汇编分析可以看到,因为不存在继承重写行为,调用的函数地址都是在编译时期确定的。1.2. 类speak函数调用栈:eat函数调用栈:sleep函数调用栈:类生成的汇编代码非常多,相比结构体复杂了很多,并且通过原创 2021-04-28 09:50:04 · 571 阅读 · 0 评论 -
Swift系列十二 - 继承
继承是面向对象语言的三大特性之一。一、继承特性值类型(枚举、结构体)不支持继承,只有类支持继承。没有父类的类,称为基类Swift并没有像OC、Java那样的规定:任何类最终都要继承自某个基类子类可以重写父类的下标、方法、属性,重写必须加上override关键字二、内存结构示例代码:class Animal { var age = 0}let a = Animal()a.age = 10print(Mems.size(ofRef: a)) // 输出:32原创 2021-04-28 09:48:58 · 790 阅读 · 1 评论 -
Swift系列十一 - 方法
枚举、结构体、类都可以定义方法。一、方法方法分为:实例方法、类型方法。实例方法: 通过实例调用类型方法: 通过类型调用,用static或者class关键字定义示例代码:class Car { static var count = 0 init() { Car.count += 1 } static func getCount() -> Int { count }}let c1 = Car()let c2 = Car()let c原创 2021-04-28 09:47:50 · 167 阅读 · 0 评论 -
Swift系列十 - inout的本质
inout是可以用来在函数内部修改外部属性内存的。一、inout回顾示例代码:func test(_ num: inout Int) { num = 20}var a = 10test(&a)print(a) // 输出:20test(&a)通过汇编分析,全局变量a的地址0x6c52(%rip)传递给了寄存器rdi,rdi作为参数传递给了test函数,所以inout的本质就是引用传递(地址传递)。二、inout本质示例代码:struct Shape {原创 2021-04-27 14:01:39 · 570 阅读 · 2 评论 -
Swift系列九 - 属性
任何一门语言都有属性的概念。Swift中的属性是怎么的呢?一、属性Swift中跟实例相关的属性可以分为2大类:存储属性和计算属性。1.1. 存储属性(Stored Property)特点:类似于成员变量的概念;存储在实例的内存中;结构体、类可以定义存储属性;枚举不可以定义存储属性。示例代码:struct Circle { var radius: Double}class classCircle { var radius: Double}关于存储属性,Sw原创 2021-04-27 14:00:31 · 269 阅读 · 0 评论 -
Swift系列八 - 闭包
什么是闭包?闭包表达式又是什么?一、闭包表达式(Closure Expression)在Swift中,可以通过func定义一个函数,也可以通过闭包表达式定义一个函数。1.1. 闭包表达式的格式{ (参数列表) -> 返回值类型 in 函数体代码}1.2. 闭包表达式和函数的比较定义一个普通的函数:func sum(_ v1: Int, _ v2: Int) -> Int { v2 + v2 }let result = sum(10, 20)print(result原创 2021-04-27 13:59:30 · 315 阅读 · 0 评论 -
Swift系列七 - 汇编分析值类型
通过汇编分下值类型的本质。一、值类型值类型赋值给var,let或者给参数传参,是直接将所有内容拷贝一份。类似于对文件进行复制粘贴操作,产生了全新的文件副本,属于深拷贝(deep copy)。示例:func testStruct() { struct Point { var x: Int var y: Int } var p1 = Point(x: 10, y: 20) print("before:p1.x:\(p1.x),p原创 2021-04-27 13:58:00 · 367 阅读 · 1 评论 -
Swift系列六 - 结构体与类的本质区别
在Swift标准库中,绝大多数的公开类型都是结构体,而枚举和类只占很小一部分。一、结构体常见的Bool、Int、Double、String、Array、Dictionary等常见类型都是结构体。自定义结构体:struct Date { var year: Int; var month: Int; var day: Int;}var date = Date(year: 2019, month: 06, day: 02)所有结构体都有一个编译器自动生成的初始化器(ini原创 2021-04-27 13:56:27 · 439 阅读 · 0 评论 -
Swift系列五 - 可选项
可选项,一般也叫可选类型,它允许将值设为nil。一、定义可选项平时开发中,如果我们需要把一个变量置空时只需要把变量赋值一个nil即可:上面尝试后不行,那怎么把一个变量置空呢?答案:把变量设置可选类型即可如何定义可选类型(可选项)?在类型后面加个问号?;定义可选项后变量默认就是nil。var age: Int?// 等价var age: Int? = nil;案例:数组越界var array = [1, 15, 20, 30]func get(_ index: Int)原创 2021-04-27 13:54:10 · 580 阅读 · 1 评论 -
Swift系列四 - 枚举
适度给类型起别名能够让代码更加易懂,开发效率更高,可维护性更好。一、typealias(别名)typealias用来给类型起别名。typealias Byte = Int8typealias Short = Int16typealias Long = Int64typealias Date = (year: Int, month: Int, day: Int)func test(_ date: Date) { print(date.year)}test((2019, 6, 25原创 2021-04-27 13:51:12 · 328 阅读 · 0 评论 -
Swift系列三 - 函数
函数在任何语言中都是存在的,Swift中函数更加灵活。一、函数的定义1.1. 有返回值(形参默认是let,也只能是let)func pi() -> Double { return 3.14}print(pi()) // 输出:3.14func sum(v1: Int, v2: Int) -> Int { return v1 + v2}print(sum(v1: 10, v2: 20)) // 输出:301.2. 无返回值func hello() ->原创 2021-04-27 13:29:27 · 198 阅读 · 0 评论 -
Swift系列二 - 循环控制
一、if-elseif后面的条件可以省略小括号条件后面的大括号不可以省略let age = 10if age >= 18 { print("大学")} else if age >= 16 { print("高中")} else { print("义务")}if后面的条件只能是Bool类型二、whilevar num = 3while num > 0 { print("num is \(num)") num -= 1原创 2021-04-27 13:27:07 · 276 阅读 · 0 评论 -
Swift系列一 - 数据类型
如果你习惯了OC的语法,第一次接触Swift的语法可能会有点抗拒,因为Swift的语法有点怪。但如果你有前端的基础,学Swift可能会有点吃力,如果你有C++的基础可能会学得比较快点。不管你有什么样的语法基础,学会Swift后你都会觉得这是门优秀的语言,总之相比哥哥OC更简洁,更高效。现在Swift的ABI版本已经到5.2了,总体趋于稳定,社区也很活跃,是系统学习的好时机。一、打印(print)可以认为是C的扩展写法:let word = "world"print("print output")原创 2021-04-27 13:14:45 · 299 阅读 · 2 评论