纯属问个问题 ^ ^
ifelseboyxx opened this issue · 3 comments
看了你这篇 《weak 弱引用的实现方式》 文章 ,里面提到 :
“单步运行,发现会跳入 NSObject.mm 中的 objc_initWeak() 这个方法。在进行编译过程前,clang 其实对 __weak 做了转换,将声明方式做出了如下调整。”
我想问下 你是怎么知道 调用 objc_initWeak
这个函数的? 我自己尝试着 clang
, 转换的代码如下:
//转换前
{
NSObject *obj = [[NSObject alloc] init];
__weak id obj1 = obj;
}
//转换后
{
NSObject *obj = ((NSObject *(*)(id, SEL))(void *)objc_msgSend)((id)((NSObject *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("NSObject"), sel_registerName("alloc")), sel_registerName("init"));
__attribute__((objc_ownership(weak))) id obj1 = obj;
}
然后 objc_ownership()
又是啥? 我在 runtime
源码里木有搜到...
原文表述确实有些问题,不能说是 Clang 对于代码的转换。感谢提出。
在 Clang 的官方文档中有以下描述:
If value is a null pointer or the object to which it points has begun deallocation, object is zero-initialized. Otherwise, object is registered as a
__weak
object pointing to value. Equivalent to the following code:
id objc_initWeak(id *object, id value) {
*addr = 0;
if (!val) return nil;
return objc_storeWeak(object, value);
}
objc_initWeak
作为 __weak
对象的初始化入口,也是 __weak
对象生命周期的第一过程。严格意义上来说只能是 Clang 对于 __weak
对象初始化的动作,说转换确实有些不太恰当。
objc_ownership
这个方法之前在 RAC 的源码中看见过,是 @weakify
和 @strongify
宏展开后调用的方法。没有看到过它的实现,但是从行为上来看应该是用来描述两个对象间的持有关系(从 Ownership 这个命名也能看出来..😂)。
最后还是多谢勘误。
clang -rewrite-objc
这个操作转换的代码和实际上编译出来的结果是有出入的(之前我在调试的时候有个很明显的例子,但是我现在忘了🤤),单步调试就可以发现会进入 objc_initWeak
函数。
__attribute__((objc_ownership(weak)))
就是 __weak
预处理后的结果,当然还会有 __strong
的那些,同样的道理。
楼上所有的应该是Block的内存布局吧。block_impl结构体内的函数指针是FuncPtr *fn。但是查看clang关于block的描述,其实应该是void (*invoke)(void *, ...);具体见这里