Runtime - 消息发送机制
objc_msgSend执行流程
OC中的方法调用,其实都是转换为objc_msgSend函数的调用
objc_msgSend的执行流程可以分为3大阶段
消息发送
动态方法解析
消息转发
源码跟读
objc-msg-arm64.s
ENTRY _objc_msgSend
b.le LNilOrTagged
CacheLookup NORMAL
.macro CacheLookup
.macro CheckMiss
STATIC_ENTRY __objc_msgSend_uncached
.macro MethodTableLookup
__class_lookupMethodAndLoadCache3
objc-runtime-new.mm
_class_lookupMethodAndLoadCache3
lookUpImpOrForward
getMethodNoSuper_nolock、search_method_list、log_and_fill_cache
cache_getImp、log_and_fill_cache、getMethodNoSuper_n ...
Runtime理解
定义
Object-C是一门动态性比较强的编程语言,跟C,C++等语言有着很大的不同
Object-C的动态性是由Runtime API来支撑的
Runtime API提供的接口基本都是C语言的,源码由C/C++/汇编编写
isa详解
学习Runtime,首先了解底层的常用数据结构,比如iso指针
在arm64架构之前,isa就是一个普通的指针,存储着Class,Meta-Class对象的内存地址
从arm64架构开始,对isa进行了优化,变成了一个共用体(union)结构,还使用位域来存储更多的信息
123456789101112131415union isa_t { Class cls; uintptr_t bits; struct { uintptr_t nonpointer : 1; uintptr_t has_assoc : 1; uintptr_t has_cxx_dtor : 1; ...
Swift-响应式编程
定义
响应式编程(Reactive Programming, 简称RP)
一种编程范式,于1997年提出,可以简化异步编程,提供更优雅的数据绑定
一般与函数式融合在一起,所以也会叫做:函数响应式编程(Functional Reactive Programming, 简称FRP)
比较著名的、成熟的响应式编程
ReactiveCocoa,简称RAC,有OC,Swift版本
官网: http://reactivecocoa.io/
github:https://github.com/ReactiveCocoa
ReactiveX,简称Rx,有众多编程语言版本,比如:RxJava, RxKotlin, RxJS, RxCpp, RxPHP, RxGo, RxSwift等等.
官网:http://reactivex.io/
github: https://github.com/ReactiveX
RxSwift
RxSwift(ReactiveX for Swift),ReactiveX的Swift版本
源码:https://github.com/ReactiveX/RxSw ...
Swift-面向协议编程
定义
面向协议编程(Protocol Oriented Programming, 简称POP)
是Swift的一种编程范式,Apple于2015年WWDC提出
在Swift标准库中,能见到大量POP的影子
同时,Swift也是一门面向对象的编程语言(Object Oriented Programming, 简称OOP)
在Swift开发中,OOP和POP是相辅相成的,任何一方并不能取代另一方
POP能弥补OOP一些设计上的不足
OOP
OOP的三大特性:封装,继承,多态
继承的经典使用场合:
当多个类(比如A, B, C类)具有很多共性时,可以将这些共性抽取到一个父类中(比如D类),最后A, B, C类继承D类
OOP的缺点
比如,如何将下面BVC, DVC的公共方法run抽取出来?1234567891011class BVC: UIViewController { func run() { print("run") } }class DVC: UITableViewController & ...
Swift-函数式编程
定义
函数式编程(Funtional Programming,简称FP)是一种编程范式,也就是如何编写程序的方法论
主要思想:把计算过程尽量分解成一系列可复用函数的调用
主要特征:函数是“第一等公民”
函数与其他数据类型一样的地位,可以赋值给其他变量,也可以作为函数参数、函数返回值
函数式编程最早出现在LISP语言,绝大部分的现代编程语言也对函数式编程做了不同程序的支持,比如:
Haskkell, JavaScript, Python, Swift, Kotlin, Scale等
函数式编程中几个常用的概念:
Higher-Order Function, Function Curring
Functor, Applicative Functor, Monad
FP实践
传统写法
12345678910// 假设要实现以下功能:[(num + 3) * 5 - 1] % 10 / 2var num = 1func add(_ v1: Int, _ v2: Int) -> Int { v1 + v2 }func sub(_ v1: Int, _ v ...
Swift-从OC到Swift 二
KVC/KVO
Swift 支持KVC/KVO的条件
属性所在的类、监听器最终继承自 NSObject
用 @objc dynamic 修饰对应的属性
KVO1234567891011121314151617181920212223242526272829303132// 监听器class Observer: NSObject { override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { print("observeValue", change?[.newKey] as Any) ...
Swift-从OC到Swift 一
MARK, TODO, FIXME
//MARK: 类似于OC中的 #pragma mark
//MARK: - 类似于OC中的 #pragma mark -
//TODO:用于标记未完成的任务
//FIXME:用于标记待修复的问题
条件编译12345678910111213141516171819202122232425262728// 操作系统:macOS\iOS\tvOS\watchOS\Linux\Android\Windows\FreeBSD#if os(macOS) || os(iOS)// CPU架构:i386\x86_64\arm\arm64#elseif arch(x86_64) || arch(arm64)// swift版本#elseif swift(<5) && swift(>=3)// 模拟器#elseif targetEnvironment(simulator)// 可以导入某模块#elseif canImport(Foundation)#else ...
Swift-Array的常见操作
map, filter, reduce, flatMap, compactMap123456789101112131415161718192021222324252627282930313233343536373839var arr = [1, 2, 3, 4]// [2, 4, 6, 8]var arr2 = arr.map { $0 * 2 }// [2, 4]var arr3 = arr.filter { $0 % 2 == 0 }// 10var arr4 = arr.reduce(0) { $0 + $1 }// 10var arr5 = arr.reduce(0, +)func double(_ i: Int) -> Int { i * 2 }var arr = [1, 2, 3, 4]// [2, 4, 6, 8]print(arr.map(double))var arr = [1, 2, 3]// [[1], [2, 2], [3, 3, 3]]var arr2 = arr.map & ...
Swift-String
关于String的思考
一个String变量战胜多少内存?
下面两个String变量,底层存储有什么不同?12var str1 = "0123456789"var str2 = "0123456789ABCDEF"
如果对String进行拼接操作,String变量的存储会发生什么变化?12345str1.append("ABCDE")str1.append("F")str1.append("G")
分析
123456789101112131415// 字符串长度 <= 0xF(16位),字符串内容直接存放在str1变量的内存中 var str1 = "0123456789" // 字符串长度 > 0xF,字符串内容存放在__TEXT.cstring中(常量区) // 字符串的地址值信息存放在str2变量的后8个字节中 var str2 = "0123456789ABCDEF" // 由于字符串长度 <= 0xF,所以字 ...
Swift-内存管理
定义
跟OC一样,Swift也是采取基于引用计数的ARC内存管理方案(针对堆空间)
Swfit的ARC中有3各引用
强引用(Strong reference):默认情况下,引用都是强引用
弱引用(weak reference):通过weak定义弱引用
必须是可选类型的var,因为实例销毁后,ARC会自动将弱引用设置为Nil
ARC自动给弱引用设置nil时,不会触发属性观察器
无主引用(unowned reference):通过unowned定义无主引用
不会产生强引用,实例销毁后仍然存储着实例的内存地址(类似于OC中的unsafe_unretained)
试图在实例销毁后访问无主引用,会产生运行时错误(野指针)
Fatal error: Attempted to read an unowned reference but object 0x0 was already deallocated
weak、unowned的使用限制
weak、owned只能用在类实例上面12345678910protocol Livable : AnyObject {}cla ...












