@interface SLAnimal : NSObject
@property(strong,nonatomic)NSString * sl_name;
- (void)saySomething;
@end
@implementation SLAnimal
- (void)saySomething{
NSLog(@"%s - %@",__func__,self.sl_name);
}
@end
在ViewController中 通过以下两种方式调用saySomething
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//下面这两种方式调用
//方式一
Class cls = [SLAnimal class];
void *sl = &cls;
[(__bridge id)sl saySomething];
//方式二:常规调用
SLAnimal *a = [SLAnimal alloc];
[a saySomething];
}
@end
2023-02-21 09:22:09.591688+0800 aaa[2244:35170] -[SLAnimal saySomething] - <ViewController: 0x7fb0daf070e0>
2023-02-21 09:22:09.591778+0800 aaa[2244:35170] -[SLAnimal saySomething] - (null)
[a saySomething]的本质是对象发送消息,a的isa指向类SLAnimal,即a的首地址指向SLAnimal的首地址,可通过LGPerson的内存平移找到cache,在cache中查找方法
[(__bridge id)sl saySomething]中的sl是来自于SLAnimal这个类,有一个指针sl,将其指向SLAnimal的首地址。
因此,a和sl都是是指向SLAnimal类的结构,都在SLAnimal中的methodList中查找方法
方式2:[a saySomething]
对于常规调用,self此时指向的是a的内存结构,获取sl_name是通过内存平移8字节获取
方式1:[(__bridge id)sl saySomething]
sl表示8字节指针,self.sl_name的获取,相当于sl首地址也需平移8字节找sl_name。sl是存在栈
中的,栈是一个先进后出
的结构,参数传入就是一个不断压栈的过程
- 隐藏参数压入栈,每个方法搜有两个隐藏参数(id self,sel _cmd)
- 隐藏参数压栈的过程,地址是递减的,栈是由高地址–>低地址分配的
- super底层调用objc_msgSendSuper,其第一个参数是一个结构体__rw_objc_super(self,class_getSuperclass),以下定义结构体,判断内部成员压栈情况。
20先加入,再加入10,所以栈中结构体内部
的成员是反向
压入栈,即低地址->高地址
,是递增的。
检验完结构体内部成员的压栈情况后,回到最初的问题,此时栈中从高到低的顺序:self –> _cmd –> (id)class_getSuperclass(objc_getClass(“ViewController“)) –> self – ->cls –> sl –> a
self
和_cmd
是viewDidLoad
方法的两个隐藏参数(id self,sel _cmd),是高地址->低地址正向压栈
的class_getSuperClass
和 self
为objc_msgSendSuper2
中的结构体成员,是从最后一个成员变量,即低地址->高地址反向压栈
的
其中发现
class_getSuperclass
是ViewController,
由于objc_msgSendSuper2
返回的是当前类
,两个self
,并不是同一个self,而是栈的指针不同,但是指向同一片内存空间
[(__bridge id)sl saySomething] 调用时,此时的sl是 SLAnimal:
0x7ff7befcab18,所以saySomething
方法中传入的self
还是SLAnimal,但并不是我们通常认为的SLAnimal,使我们当前传入的消息接收者
,即SLAnimal:
0x7ff7befcab18,是SLAnimal的实例对象,此时的操作与普通的SLAnimal是一致的,即SLAnimal的地址内存平移8字节
sl流程:
0x7ff7befcab18 + 0x80 –> 0x7ff7befcab20, 即为self
所以sl查找sl_name时候“欺骗”了编译器, 在栈中内存平移8字节(0x7ff7befcab18 + 0x80 = 0x7ff7befcab20 = ViewController)
补充
注意:
原文地址:https://blog.csdn.net/weixin_38016552/article/details/129135994
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_29236.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!