建了个裙,群号:812157648,有兴趣的可以加一下,大家一起相互学习。
一.算法
两个数n、m 如果是n= 2 m=5,用递归实现2 3 4 5相加等于14;
public static int sum(int n1, int n2) {
if(n1 == n2) {
return n1;
}
if(n1 > n2) {
int temp = n1;
n1 = n2;
n2 = temp;
}
return sum(n1, n2-1) + n2;
}
二.weak和assign的区别
1、区别
修饰变量类型的区别
weak 只可以修饰对象。如果修饰基本数据类型,编译器会报错-“Property with ‘weak’ attribute must be of object type”。
assign 可修饰对象,和基本数据类型。当需要修饰对象类型时,MRC时代使用unsafe_unretained。当然,unsafe_unretained也可能产生野指针,所以它名字是"unsafe_”。是否产生野指针的区别
weak 不会产生野指针问题。因为weak修饰的对象释放后(引用计数器值为0),指针会自动被置nil,之后再向该对象发消息也不会崩溃。 weak是安全的。
assign 如果修饰对象,会产生野指针问题;如果修饰基本数据类型则是安全的。修饰的对象释放后,指针不会自动被置空,此时向对象发消息会崩溃。
2、相似
都可以修饰对象类型,但是assign修饰对象会存在问题。
3、总结
assign 适用于基本数据类型如int,float,struct等值类型,不适用于引用类型。因为值类型会被放入栈中,遵循先进后出原则,由系统负责管理栈内存。而引用类型会被放入堆中,需要我们自己手动管理内存或通过ARC管理。
weak 适用于delegate和block等引用类型,不会导致野指针问题,也不会循环引用,非常安全。
三.weak原理(很细致,具体到如何查找的)
1、调用objc_release
2、因为对象的引用计数为0,所以执行dealloc
3、在dealloc中,调用了_objc_rootDealloc函数
4、在_objc_rootDealloc中,调用了object_dispose函数
5、调用objc_destructInstance
6、最后调用objc_clear_deallocating。
详情
四.autoreleasePool 的结构和自动释放池中的对象存储过程,autoreleasePool的结构。(比较细致的问了一遍过程)
关键字:结构体 parent和child 双向链表
详情
五.objc_msgSend()经历的过程,具体到cache_t结构和具体hashmap的查找方法。动态解析和消息转发要说具体的方法名称。
objc_msgSend汇编部分仅仅完成很少的缓存查找功能,如果找不到就会调用C方法去对象的方法二维数组中找,找不到再查父类的缓存(这也是汇编实现的)和父类的方法数组,一直找到根类,如果此过程中找到对应的方法则调用并添加缓存,如果没有找到,则表明该继承体系都没有直接实现该方法,这时runtime会调用对象的方法决议去尝试解决。如果不行则由CoreFoundation框架提供的forwarding来转发到其他对象处理,若还不能处理则抛出异常。
详情
六.block的捕获机制,block类型的区分,__block做了什么,__block修饰对象类型和基本数据类型的区别。
全局堆栈带__block的自动变量 和 静态变量 就是直接地址访问。所以在Block里面可以直接改变变量的值。
剩下的静态全局变量,全局变量,函数参数,也是可以在直接在Block中改变变量值的,但是他们并没有变成Block结构体__main_block_impl_0的成员变量,因为他们的作用域大,所以可以直接更改他们的值。
详情上
详情下
七.load()和initialize()区别
调用方式
1、load是根据函数地址直接调用
2、initialize是通过objc_msgSend调用
调用时刻
1、load是runtime加载类、分类的时候调用(只会调用一次)
2、initialize是类第一次接收到消息的时候调用, 每一个类只会initialize一次(如果子类没有实现initialize方法, 会调用父类的initialize方法, 所以父类的initialize方法可能会调用多次)
load和initializee的调用顺序
1、load:父子分
先调用类的load, 在调用分类的load
先编译的类, 优先调用load, 调用子类的load之前, 会先调用父类的load
先编译的分类, 优先调用load
2、initialize 分子父
先初始化分类, 后初始化子类
通过消息机制调用, 当子类没有initialize方法时, 会调用父类的initialize方法, 所以父类的initialize方法会调用多次
八.图层方法两倍形变后,frame和bouns的变化,相对位置,绝对位置。
阅读原文