oc7--内存分析

//
//  main.m
//  第二个OC类

#import <Foundation/Foundation.h>

@interface Person : NSObject
{
    @public
    int _age;
    double _height;
    double _weight;
}
- (void)eat:(char *)food;
- (void)sleep;
- (void)walk;
+ (void)demo;
@end
@implementation Person
- (void)eat:(char *)food
{
    NSLog(@"吃%s", food);
}
- (void)sleep
{
    NSLog(@"开始睡觉");
}
- (void)walk
{
    NSLog(@"开始遛弯");
}
+(void)demo
{
    NSLog(@"demo");
}
@end


int main(int argc, const char * argv[]) {
    
    // 1.通过类创建对象
    /*
     内存区域分为:栈、堆、代码区(存放二进制代码)。
     1.程序启动会把Person的代码放在代码区(Person的申明和实现的代码都在代码区了)。
     2.new 创建对象会在堆中开辟存储空间给Person对象(有属性,属性初始化为0)。
     3.指针名在栈中。存的是Persion对象的地址(堆中的地址)。(结构体的地址是第0个元素的地址)
     
     4.创建对象的时候返回的地址其实就是类的第0个属性的地址,但是需要注意的是: 类的第0个属性并不是我们编写的_age, 而是一个叫做isa的属性(系统添加的第0个属性),isa是一个指针, 占8个字节。(结构体的地址是第0个元素的地址,类的本质就是结构体,所以类返回的地址就是第0个元素的地址。)
     
     5.其实类也是一个对象, 也就意味着Person也是一个对象,平时我们所说的创建对象其实就是通过一个 类对象 来创建一个 新的对象,类对象是系统自动帮我们创建的(当Person类代码加载到代码区的时候系统就会根据这个代码创建一个Person类对象,类对象存放在堆区, 里面保存了当前对象的所有方法), 而实例对象是程序自己手动通过new来创建的, 而实例对象中有一个isa指针(第0个属性,is a是什么)就指向了创建它的那个类对象。p的地址就是isa的地址。
     
     6.类方法:直接找到类对象,调用类方法。所以类方法执行的效率高。
     
     */
    Person *p = [Person new];
    p->_age = 30;
    p->_height = 1.75;
    p->_weight = 65.0;
    
    NSLog(@"age = %i , height = %f, weight = %f,isa = %p", p->_age, p->_height, p->_weight);
    
    NSLog(@"p = %p", p);//0x1002035e0
    NSLog(@"&age = %p", &(p->_age));//0x1002035e8, p的地址和age的地址相差8就是isa占了8个字节,苹果的文档已经写的很清楚了。
    
    [p walk];//首先找到栈中p的地址,然后找到p的地址指向的堆中person对象的地址,然后找到isa指针,然后找到Person类对象,然后找到walk方法。
    [Person demo];
    
    
/////////////////////////////////////////////
    struct Person
    {
        int age;
        char *name;
    };
    struct Person sp;
    NSLog(@"&sp = %p", &sp);
    NSLog(@"&age = %p", &sp.age);   //结构体的地址是第0个元素的地址,类的本质就是结构体,所以类返回的地址就是第0个元素的地址。

    ////////////////////////////////////////////
    
    return 0;
}

原文地址:https://www.cnblogs.com/yaowen/p/7410768.html