一: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 方法名];
可以调用其他的对象方法或者是类方法