在以前的博客中,对OC底层进行了一系列的探索分析,相信小伙伴们都学到了必定的知识,可是底层源码分析比较枯燥,那么本次就对一些面试题进行分析。 c++
在上篇博客iOS底层探索之类的加载(四):类的关联对象AssociatedObject中主要讲了类的扩展
和类的关联对象
,移除关联
尚未讲,这里就作一点补充。面试
objc_removeAssociatedObjects
void objc_removeAssociatedObjects(id object)
{
if (object && object->hasAssociatedObjects()) {
_object_remove_assocations(object, /*deallocating*/false);
}
}
复制代码
_object_remove_assocations
void
_object_remove_assocations(id object, bool deallocating)
{
ObjectAssociationMap refs{};
{
AssociationsManager manager;
AssociationsHashMap &associations(manager.get());
AssociationsHashMap::iterator i = associations.find((objc_object *)object);
if (i != associations.end()) {
refs.swap(i->second);
// If we are not deallocating, then SYSTEM_OBJECT associations are preserved.
bool didReInsert = false;
if (!deallocating) {
for (auto &ref: refs) {
if (ref.second.policy() & OBJC_ASSOCIATION_SYSTEM_OBJECT) {
i->second.insert(ref);
didReInsert = true;
}
}
}
if (!didReInsert)
associations.erase(i);
}
}
// Associations to be released after the normal ones.
SmallVector<ObjcAssociation *, 4> laterRefs;
// release everything (outside of the lock).
for (auto &i: refs) {
if (i.second.policy() & OBJC_ASSOCIATION_SYSTEM_OBJECT) {
// If we are not deallocating, then RELEASE_LATER associations don't get released.
if (deallocating)
laterRefs.append(&i.second);
} else {
i.second.releaseHeldValue();
}
}
for (auto *later: laterRefs) {
later->releaseHeldValue();
}
}
复制代码
上面👆这是移除关联对象的代码,这里就不过多分析源码了,咱们看看在哪里调用了数组
在对象的生命周期,
dealloc
的时候markdown
dealloc
// Replaced by NSZombies
- (void)dealloc {
_objc_rootDealloc(self);
}
复制代码
_objc_rootDealloc
void
_objc_rootDealloc(id obj)
{
ASSERT(obj);
obj->rootDealloc();
}
复制代码
对象释放就会去找rootDealloc
app
rootDealloc
inline void
objc_object::rootDealloc()
{
if (isTaggedPointer()) return; // fixme necessary?
if (fastpath(isa.nonpointer &&
!isa.weakly_referenced &&
!isa.has_assoc &&
#if ISA_HAS_CXX_DTOR_BIT
!isa.has_cxx_dtor &&
#else
!isa.getClass(false)->hasCxxDtor() &&
#endif
!isa.has_sidetable_rc))
{
assert(!sidetable_present());
free(this);
}
else {
object_dispose((id)this);
}
}
复制代码
这里会判断isa.nonpointer
、弱引用isa.weakly_referenced
、关联对象isa.has_assoc
等等,有的话就进入object_dispose
。ide
object_dispose
id
object_dispose(id obj)
{
if (!obj) return nil;
objc_destructInstance(obj);
free(obj);
return nil;
}
复制代码
进入objc_destructInstance
销毁实例函数
objc_destructInstance
void *objc_destructInstance(id obj)
{
if (obj) {
// Read all of the flags at once for performance.
bool cxx = obj->hasCxxDtor();
bool assoc = obj->hasAssociatedObjects();
// This order is important.
if (cxx) object_cxxDestruct(obj);
if (assoc) _object_remove_assocations(obj, /*deallocating*/true);
obj->clearDeallocating();
}
return obj;
}
复制代码
C++
方法,关联对象
方法判断,就去走_object_remove_assocations
也就是最开头的那个移除关联对象方法。oop
因此,关联对象不须要咱们手动移除,会在
dealloc
时自动进行释放源码分析
load
是在dyld
回调load_images
中进行调用的,这个回调是在_objc_init
的过程当中进行注册的。C++
构造函数对于同一个image
而言是在load
回调后dyld
调用的。(并非绝对的)image
内部是先加载全部类的+ load
,再加载分类的+ load
,最后加载C++
全局构造函数。(类load
-> 分类load
-> C++
构造函数)。+load
是objc
中调用的,C++
全局构造函数是在dyld
中调用的。(image
内部的顺序默认是按Compile Sources
中顺序进行加载的,固然对于有依赖库的image
,依赖库+load先被调用)。Dyld
初始化image
是按Link Binary With Libraries
顺序逐个初始化的,从下标1开始,最后再初始化主程序(下标0)。image
而言C++
构造函数在load
以后调用并非绝对的。好比objc
系统库,在进行dyld
注册回调以前调用了自身库的C++
构造函数(自启)。runtime
是由C
和C++
/ 汇编
实现的⼀套API
,为OC
语⾔加⼊了⾯向对象,运⾏时的功能。dyld
、汇编
、objc
、macho
才是底层。OC
代码,在程序运行过程当中,其实最终会转换成Runtime
的C
语言代 码,Runtime
是 Objective-C
的幕后工做者。initialize
是在第一次发送消息的时候进行的调用。学习
load
是在load_images的时候调用的,load
比initialize
调用时机早(initialize
在lookupimporforward
慢速消息查找的时候调用)。
整个调用顺序load
> C++构造函数
> initialize
。
同名分类方法调用顺序分为两种状况:
在iOS底层探索之类的加载(三): attachCategories分析博客里面也介绍了分类和load方法的一些加载。
首先咱们来看看什么是分类和扩展
category
: 类别/分类
- 专门用来给类添加新的方法
- 不能给类添加成员属性,添加了成员变量,也没法取到
注意
:其实能够经过runtime
给分类添加属性- 分类中用
@property
定义变量,只会生成变量的getter,setter
方法的声明,不能生成方法实现和带下划线的成员变量
。
extension
:类扩展
- 能够说成是特殊的分类,也称做
匿名分类
- 能够给类添加
成员属性
,可是是私有变量
- 能够给类添加方法,也是
私有方法
分类咱们已经很熟悉了,这里就没必要过多赘述了,下面介绍下扩展
extension
类扩展,咱们平时用的是很是多的,以下
what ? 什么,这就是扩展吗?每天用竟然不知道!
是的,这就是扩展,平时用的是很是之多,可是不少人都不知道。
注意
:类扩展要放在声明以后,实现以前,不然会报错。
更多内容持续更新
🌹 喜欢就点个赞吧👍🌹
🌹 以为有收获的,能够来一波,收藏+关注,评论 + 转发,以避免你下次找不到我😁🌹
🌹欢迎你们留言交流,批评指正,互相学习😁,提高自我🌹