首页 > 代码库 > OC中description、 SEL、类本质、self和super用法

OC中description、 SEL、类本质、self和super用法

一:description方法

description有对象方法和类方法两种,(是NSObject类的方法)

1,-description(对象方法)

使用NSLog和@%输出某个对象时,会调用对象的description方法,并拿到返回值进行输出。(系统会自动调用打印对象的description方法)

而如果打印NSString对象的话,默认返回的就是NSString字符串

2,+description (类方法)

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

系统默认会直接调用NSObject父类的description方法,返回对象的名和地址打印出来

所以如果我们想要打印属性值的话就需要重写description的方法

#import <Foundation/Foundation.h>

@interface Car : NSObject

{

@public

    int _lunzi;

    int _seats;

    NSString *_name;

}

-(void)run;

@end

@implementation Car

-(void)run{

    

    NSLog(@"三胖驾车跑了");

    

}

//重写父类的description方法

-(NSString *)description{

    

    return [NSString stringWithFormat:@"name:%@,lunzi:%d,seats:%d",_name,_lunzi,_seats];

    

    //self car

    //return [NSString stringWithFormat:@"aaaa-%@",self];

}

 

+(NSString *)description{

    

    return @"xxxx";

    

}

@end

 

int main(int argc, const char * argv[])

{

        Car *car = [Car new];

        car->_name = @"大切";

        car->_lunzi= 8;

        car->_seats= 10;

        

        //%@ 可以打印OC中的对象类型

        //NSString *str = @"xxxx";

        //注意:当我们使用%@ 打印car(对象)的时候,会调用我们类的

        //                       -(NSString *)descrition;

        //

        Class c = [car class];

        NSLog(@"\ncar:%@",car);

        NSLog(@"\nCar:%@",c);

        NSLog(@"name:%@,lunzi:%d,seats:%d",car->_name,car->_lunzi,car->_seats);

        return 0;

}

 

 

 

二:类的本质

   类本身也是一个对象,是class类型的对象,简称“类对象”。

Class类型的定义: Typedef struct obj class *class;

可以看到类对象的类型为struct 0bj class *  及指向结构体地址的指针类型
 
获取内存中的类对象有两种方法:(一个类的类对象只有一个及内存分配一个相同的空间

(1)Class c=[p class];  //指向类的对象的指针调用class方法

(2)Class c1=[Person class]; //使用类名调用class方法

 

类对象本质图解:

类———————类对象-------------实例对象
在编译时就会将类加载到代码区
然后加载类对象到堆区
后三步为对象的加载,并且实例对象的isa指针指向类对象。类对象中isa指针指向类。(而且类对象中得SEL映射表为类中方法地址
 
三:SEL:全称Selector 表示方法的存储位置。sel是一种数据类型,存放方法的地址,在类对象的映射表里面存放着映射关系
 
Person *p=[[Person alloc] init];

        [p test];

实例对象寻找方法的过程

1>首先将方法包装成sel数据类型的数据  SEL *sel = @selector(方法名)

2>然后根据SEL找方法的地址

3>根据方法的地址调用相应的方法

4)注意:在这个操作过程中有缓存,第一次找的时候是一个一个的找,非常耗性能,之后再用到的时候就直接使用。

关于_cmd:每个方法的内部都有一个-cmd,代表着当前方法。

//SEL是一种数据类型,获取方法的地址

SEL s1 = @selector(run);   //取出run的地址

 [p2 performSelector:s1];   //间接的调用run

 

注意:SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去寻找对应的方法地址,找到方法地址后就可以调用方法。这些都是运行时特性,发消息就是发送SEL,然后根据SEL找到地址,调用方法。

 

四:self和super的用法: 

self、super是一个指针,self谁调用了当前方法,self就指向谁

而super指向了当前类的父类,如果super在类方法中,它就代表了调用当前类方法的类的父类,如果在对象方法中,它就代表调用当前对象方法的对象的父类对象

1>如果self、super在类方法中,那么它就代表当前调用这个类方法的类、父类
2>如果self在对象方法中,那么它就代表当前调用这个对象方法的对象、父对象

出现在对象方法中,就代表着当前对象,出现在类方法中,就代表着当前类】

Self、super的用途:通下

(1)可以利用self->成员变量名访问当前对象内部的成员变量(仅在对象方法中)

(2)[self 方法名];可以调用其他的对象方法或者是类方法

 

OC中description、 SEL、类本质、self和super用法