class和static的区别
- static修饰的属性或者方法,子类不能重写;
static方法类似于class final方法;
- 在类中的方法派发,二者不同;
- 在SIL代码中,class方法存储在V-Table中,static方法是以静态方法的形式存储;
struct无法代替class的一些场景
- 需要使用继承调用super,无法使用struct
- 需要使用引用类型
- 需要使用deinit
- 需要在运行时动态转换一个实例的类型
Extension扩展属性
- 默认是不允许扩展存储属性的,无法给属性添加观察者;
- 可添加计算属性;
- 可添加是他提出静态属性,因为静态属性分配内存是在全局区的;
- 可通过关联对象的方法,添加属性;
- 不允许重载已存在的方法;
extension Person {
private static var AGE_KEY = false
var age: Int {
get {
objc_getAssociatedObject(self, &Self.AGE_KEY) as! Int
}
set {
objc_setAssociatedObject(self, &Self.AGE_KEY, newValue, .OBJC_ASSOCIATION_ASSIGN)
}
}
}
闭包知识点
- 闭包是一个捕获了上下文的常量或者是变量的函数一个引用类型;
- 闭包捕获值的本质,是在堆区开辟内存,然后存储其捕获到上下文的值;
- 修改捕获值也只是修改堆区的值;
- 闭包的底层结构是结构体,首先存储闭包的地址,加上捕获值的地址;
- 在捕获的值中,会对存储的变量和函数的参数分开存储;
- 存储的时候,内部会有一个
HeapObject结构,用于管理内存和引用计数;
-
- 函数是特殊的闭包, 只不过函数不捕获值, 所以在闭包结构体中只存储函数地址, 不存储指向捕获值的指针.
正负数的原码、反码和补码
- 正数的符号位是0,负数的符号位是1
- 原码:正数与负数的原码都是是,符号位 + 二进制真值 (+1 -> 0000 0001) (-1 -> 1000 0001)
- 补码:正数的补码是和源码相同(+1 -> 0000 0001);负数的补码是,除符号位外,其它位取反;(-1 -> 1111 1110)
- 反码:正数的补码是和源码相同(+1 -> 0000 0001);负数的补码是,补码 + 1(-1 -> 1111 1111)
枚举
- 不带关联值的枚举,系统会默认帮我们实现
Hashable/Equatable协议,可进行== 与 !=操作;
- 简单枚举<没有关联值>的本质就是一个整型值,整型值的大小取决于该枚举所定义的类型的数量;
- 给枚举添加原始值不会影响枚举自身的任何结构,设置原始值其实是编译器帮我们添加了
rawValue属性,init(rawValue)方法(RawRepresentable协议);
- 添加/调用"实例方法"、"类型方法"、计算属性以及实现协议的本质都是添加/调用函数;