返回

洞悉iOS类对象内存存在个数(上)

IOS

类对象内存存在个数分析

01、首先,我们创建一个LGPerson类继承于NSObject

// Person.h
#import <Foundation/Foundation.h>

@interface LGPerson : NSObject

@end

// Person.m
#import "Person.h"

@implementation LGPerson

@end

02、通过不同获取类对象的方法来进行验证

int main(int argc, char * argv[]) {
    @autoreleasepool {
        // 1.使用objc_getClass方法
        Class personClass = objc_getClass("LGPerson");
        
        // 2.使用object_getClass方法
        id person = [[LGPerson alloc] init];
        Class personClass2 = object_getClass(person);
        
        // 3.使用class方法
        Class personClass3 = [LGPerson class];
        
        // 打印结果
        NSLog(@"personClass: %p", personClass);
        NSLog(@"personClass2: %p", personClass2);
        NSLog(@"personClass3: %p", personClass3);
    }
    return 0;
}

03、打印结果:

personClass: 0x104007a20
personClass2: 0x104007a20
personClass3: 0x104007a20

04、我们发现类对象有且只有一个。

isa流程探索

01、我们继续用LGPerson类来进行探索

// Person.h
#import <Foundation/Foundation.h>

@interface LGPerson : NSObject

@end

// Person.m
#import "Person.h"

@implementation LGPerson

- (void)test {
    NSLog(@"%p", self);
    NSLog(@"%p", [self class]);
    NSLog(@"%p", object_getClass(self));
}

@end

02、在main函数中创建LGPerson对象并调用test方法

int main(int argc, char * argv[]) {
    @autoreleasepool {
        LGPerson *person = [[LGPerson alloc] init];
        [person test];
    }
    return 0;
}

03、打印结果:

0x1041c7060
0x104007a20
0x104007a20

04、self指针指向的是对象本身的内存地址,[self class]和object_getClass(self)指向的都是类对象的内存地址。
05、这说明isa指针指向的是类对象的内存地址。

class_getInstanceSize探索

01、class_getInstanceSize函数可以获取到类对象的实例大小

#import <Foundation/Foundation.h>

@interface LGPerson : NSObject

@end

@implementation LGPerson

- (void)test {
    NSLog(@"%zu", class_getInstanceSize([self class]));
}

@end

int main(int argc, char * argv[]) {
    @autoreleasepool {
        LGPerson *person = [[LGPerson alloc] init];
        [person test];
    }
    return 0;
}

02、打印结果:

16

03、这说明LGPerson类对象的实例大小为16字节。

NSLog探索

01、NSLog函数可以将各种类型的数据输出到控制台

#import <Foundation/Foundation.h>

@interface LGPerson : NSObject

@end

@implementation LGPerson

- (void)test {
    NSLog(@"%p", self);
    NSLog(@"%p", [self class]);
    NSLog(@"%zu", class_getInstanceSize([self class]));
}

@end

int main(int argc, char * argv[]) {
    @autoreleasepool {
        LGPerson *person = [[LGPerson alloc] init];
        [person test];
    }
    return 0;
}

02、打印结果:

0x1041c7060
0x104007a20
16

03、NSLog函数可以将对象本身的内存地址、类对象的内存地址、类对象的实例大小等信息输出到控制台。

内存地址探索

01、内存地址是计算机中用于标识内存位置的编号

#import <Foundation/Foundation.h>

@interface LGPerson : NSObject

@end

@implementation LGPerson

- (void)test {
    NSLog(@"%p", self);
    NSLog(@"%p", [self class]);
    NSLog(@"%zu", class_getInstanceSize([self class]));
}

@end

int main(int argc, char * argv[]) {
    @autoreleasepool {
        LGPerson *person = [[LGPerson alloc] init];
        [person test];
    }
    return 0;
}

02、打印结果:

0x1041c7060
0x104007a20
16

03、内存地址是十六进制数字,用于标识内存中的具体位置。