- 关联对象是一个全局的manger管理的 一个hash表,不是依附于实例对象的,在类别中新建property,在class 中只有声明set/get方法,没有实现,需要自己在cateroty中手动实现,实现方式1:静态变量;实现方式2是:用关联对象手动set和get在
AssociationsManager
管理的hash表中。在实例dealloc
中,会执行if (assoc) _object_remove_assocations(obj);
来销毁释放对象。 - 销毁对象的时候 销毁系统维护的weak表方法是:
obj->clearDeallocating();
- 销毁对象执行的操作
runtime源码解析
objc_object::rootDealloc()
{
if (isTaggedPointer()) return; // fixme necessary?
if (fastpath(isa.nonpointer &&
!isa.weakly_referenced && //weak表
!isa.has_assoc && //关联对象
!isa.has_cxx_dtor && //是否有C++析构函数,如果没有,释放时会更快
!isa.has_sidetable_rc))//有没有父类引用
{
assert(!sidetable_present());
free(this);
}
else {
object_dispose((id)this);//销毁操作
}
}
- 局部变量都会被block捕获,自动变量是值捕获,静态变量为地址捕获。全局变量则不会被block捕获。
- block 不能修改aotu 变量,因为int是值传递,不是地址,不能修改。copy strong修饰的block是讲block从栈区拷贝到了堆区。
全局变量能修改,因为传递进去的是指针地址。 -
__block
修饰的int类型会再block内部生成一个结构体,赋值和取值用age-> __forwarding
来实现。内存地址是自己的结构体的内存地址,age的地址其实是外部的内存地址
结构体包含int变量的内存大小和内存地址,销毁block的时候将结构体传给dispose
进行引用-1操作 - global malloc stack 三种block 全局的是没有访问aotu变量的,copy 和dispatch 是在堆区的,stack是栈区的,访问了auto变量的block,执行完就销毁。
block内存管理
复制到堆上边 修改int变量
对象类型复制copy操作会把stack转换成mallocblock,arc情况下 copy自动转换到堆上然后修改值
对象类型复制到堆上然后修改值-
tcp三次握手四次挥手
tcp/udp/http 分层
建立起一个TCP连接需要经过“三次握手”:
第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
[图片上传失败...(image-bc4c1e-1555049052609)]
- runtime class 存储method sel 在cache中使用 sel&mask,保证不会内存溢出,当容量小余3/4时候进行扩容,容量为原来的2倍。
-
runtime 消息转发机制
汇编语言中_objc_msgSend的运行流程 - OC中的方法调用其实都是转成了objc_msgSend函数的调用,给receiver(方法调用者)发送了一条消息(selector方法名)。方法调用过程中也就是objc_msgSend底层实现分为三个阶段:
1.消息发送[class和instance寻找sel]
2.动态方法解析[reslo方法可以动态添加method]
3.消息转发[method_sign 方法签名可以返回自己想要的实例,然后该实例调用方法]
详情见博客
消息转发阶段
网友评论