• CO-类的本质、description方法


    类的本质

    1. 类也是个对象

    • 其实类也是一个对象,是Class类型的对象,简称“类对象”
    • Class类型的定义

    typedef struct objc_class  *Class;

    • 类名就代表着类对象,每个类只有一个类对象

    2. +load和+initialize

    • +load

    l   在程序启动的时候会加载所有的类和分类,并调用所有类和分类的+load方法

    l   先加载父类,再加载子类;也就是先调用父类的+load,再调用子类的+load

    l   先加载元原始类,再加载分类

    l   不管程序运行过程有没有用到这个类,都会调用+load加载

    • +initialize

    l   在第一次使用某个类时(比如创建对象等),就会调用一次+initialize方法

    l   一个类只会调用一次+initialize方法,先调用父类的,再调用子类的

    3. 获取类对象的2种方式

    Class c = [Person class];// 类方法 

    或者

    Person*p = [Person new];

    Class c2 = [p class];// 对象方法

     

    4. 类对象 调用类方法

    Class c = [Person class];  

    Person *p2 = [c new];

     

    #import <Foundation/Foundation.h>
    #import "Person.h"
    #import "Student.h"
    #import "GoodStudent.h"
    /*
     1.当程序启动时,就会加载项目中所有的类和分类,而且加载后会调用每个类和分类的+load方法。只会调用一次。
     
     2.当第一次使用某个类时,就会调用当前类的+initialize方法
     
     3.先加载父类,再加载子类(先调用父类的+load方法,再调用子类的+load方法)
       先初始化父类,再初始化子类(先调用父类的+initialize方法,再调用子类的+initialize方法)
     */
    
    int main()
    {
        // [[GoodStudent alloc] init];
        
        return 0;
    }
    
    void test1()
    {
        Person *p = [[Person alloc] init];
        
        //[Person test];
        
        // 内存中的类对象
        // 类对象 == 类
        Class c = [p class];
        [c test];
        
        Person *p2 = [[c new] init];
        
        
        NSLog(@"00000");
    }
    
    void test()
    {
        // 利用Person这个类创建了2个Person类型的对象
        Person *p = [[Person alloc] init];
        
        Person *p2 = [[Person alloc] init];
        
        Person *p3 = [[Person alloc] init];
        
        // 获取内存中的类对象
        Class c = [p class];
        
        Class c2 = [p2 class];
        
        // 获取内存中的类对象
        Class c3 = [Person class];
        
        
        NSLog(@"c=%p, c2=%p, c3=%p", c, c2, c3);
        
        //  类本身也是一个对象,是个Class类型的对象,简称类对象
        
        /*
         利用Class 创建  Person类对象
         
         利用 Person类对象 创建 Person类型的对象
         
         */

    description方法

    使用场合: 

    1.      -description方法

    使用NSLog和%@输出某个对象时,会调用对象的-description方法,并拿到返回值进行输出

    返回: <类名: 内存地址>

    2.      +description方法

    使用NSLog和%@输出某个类对象时,会调用类对象+description方法,并拿到返回值进行输出

    3.      修改NSLog的默认输出

    l   重写-description或者+description方法即可

    4.      死循环陷阱

    l   如果在-description方法中使用NSLog打印self

    #import <Foundation/Foundation.h>
    #import "Person.h"
    
    
    void test9()
    {
        // 输出当前函数名
        NSLog(@"%s
    ", __func__);
    }
    
    int main()
    {
        // 输出行号
        NSLog(@"%d", __LINE__);
        
        // NSLog输出C语言字符串的时候,不能有中文
        // NSLog(@"%s", __FILE__);
        
        // 输出源文件的名称
        printf("%s
    ", __FILE__);
        
        test9();
        
        Person *p = [[Person alloc] init];
        
        // 指针变量的地址
        NSLog(@"%p", &p);
        // 对象的地址
        NSLog(@"%p", p);
        // <类名:对象地址>
        NSLog(@"%@", p);
       
        return 0;
    }
    
    void test2()
    {
        Class c = [Person class];
        
        // 1.会调用类的+description方法
        // 2.拿到+description方法的返回值(NSString *)显示到屏幕上
        NSLog(@"%@", c);
    }
    
    void test1()
    {
        Person *p = [[Person alloc] init];
        p.age = 20;
        p.name = @"Jack";
        // 默认情况下,利用NSLog和%@输出对象时,结果是:<类名:内存地址>
        
        // 1.会调用对象p的-description方法
        // 2.拿到-description方法的返回值(NSString *)显示到屏幕上
        // 3.-description方法默认返回的是“类名+内存地址”
        NSLog(@"%@", p);
        
        //Person *p2 = [[Person alloc] init];
        //NSLog(@"%@", p2);
        
        //NSString *name = @"Rose";
        
        //NSLog(@"我的名字是%@", name);
        
        Person *p2 = [[Person alloc] init];
        p2.age = 25;
        p2.name = @"Jake";
        
        NSLog(@"%@", p2);
    }
    #import "Person.h"
    
    @implementation Person
    
    // 决定了实例对象的输出结果
    //- (NSString *)description
    //{
    //    // 下面代码会引发死循环
    //    // NSLog(@"%@", self);
    //    return [NSString stringWithFormat:@"age=%d, name=%@", _age, _name];
    //    //return @"3424324";
    //}
    
    // 决定了类对象的输出结果
    + (NSString *)description
    {
        return @"Abc";
    }
    
    @end
  • 相关阅读:
    PPT入门学习笔记1:待修改
    单片机入门学习笔记8:STM32单片机使用
    springboot中redis做缓存时的配置
    LocalDateTime与mysql日期类型的交互(基于mybatis)
    LocalDateTime在spring boot中的格式化配置
    Spring Cloud学习笔记【十】配置中心(消息驱动刷新配置)
    Spring Cloud学习笔记【九】配置中心Spring Cloud Config
    Spring Cloud分布式Session共享实践
    Spring Cloud学习笔记【八】服务网关 Zuul(过滤器)
    Spring Cloud学习笔记【七】服务网关 Zuul(路由)
  • 原文地址:https://www.cnblogs.com/IDRI/p/4956369.html
Copyright © 2020-2023  润新知