iOS底层系列之<21>--Runtime(八)函数栈问题

1、问题引出

  • 打印结果是什么?
// Person.h 文件
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
- (void)print;
+ (void)print;
@end
// Person.m 文件
#import "Person.h"

@implementation Person
- (void)print {
    NSLog(@"my name is -- %@",self.name);
}
+ (void)print {
    NSLog(@"11");
}
@end
// ViewController.m 文件
#import "ViewController.h"
#import "Person.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSString *test = @"abc";
    
    id cls = [Person class];
    void *obj = &cls;
    [(__bridge id)obj print];
}


@end
  • obj 和普通的person实现对象内存分析对比图
    在这里插入图片描述
  • 这个问题暂时先放一放,不着急回答,请继续往下看。

2、函数栈问题知识补充

  • 1、关于函数栈的地址问题
void test() {
    long long int a = 1;
    long long int b = 2;
    long long int c = 3;
    long long int d = 4;
    
    NSLog(@"%p %p %p %p", &a,&b,&c,&d);
    // 0x7ffee14f7b68 0x7ffee14f7b60 0x7ffee14f7b58 0x7ffee14f7b50
}

从打印结果,可以看出,a~d,4个变量,地址是从高到低排序。


  • 在普通的person对象中,内存结构方式如下图所示
    在这里插入图片描述
  • 在当前这种情况下,内存结构方式如下图所示

在这里插入图片描述

  • 两个图一对比,就可以发现,如果是正常给person的name赋值后,就会通过isa,往后面寻找8个地址,直接找到name指针指向的堆空间
  • 在当前这种情况,往后面寻找8个字节地址,找到的是test指针指向的堆空间,误认为test的指针指向的内容就是name指向的内容

结论:最终会调用到test指针指向的堆内存空间,打印结果"my name is – abc"


  • 如果代码是这样写的
- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSString *test = @"abc";
    NSString *test1 = @"123";

    id cls = [Person class];
    void *obj = &cls;
    [(__bridge id)obj print];
    
    NSLog(@"--");
}
  • 那么内存分布结构如下图
    在这里插入图片描述

打印结果,很容易得出:“my name is – 123”


如果只有 [super viewDidLoad];

- (void)viewDidLoad {
    [super viewDidLoad];
    // 相当于
    struct tempCls = {
        self,
        [ViewController class]
    };
    objc_msgSendSuper2(abc, sel_registerName("viewDidLoad"));
// 内部实际上会[ViewController class]->getSuperclass
//    NSString *test = @"abc";
//    NSString *test1 = @"123";

    id cls = [Person class];
    void *obj = &cls;
    [(__bridge id)obj print];
//    Person *person = [[Person alloc] init];
//    person.name = @"张三";
    
    NSLog(@"--");
}
  • 内存结构图如下
    在这里插入图片描述

所以打印结果如下:my name is – <ViewController: 0x7fad621069d0>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值