关于NSObject和运行时系统
类NSObject
OC作为一门动态编程语言,有很多动态的特性,OC不仅需要编译环境,还需要一个运行时系统(runtime system)来执行编译好的代码。运行时系统扮演的角色类似于OC的操作系统,它负责独立完成对象的生成,释放时的内存管理等。
程序中无法直接使用运行时系统提供的功能。根类方法中提供了运行时系统的基本功能,继承了NSObject的所有类都可以自由地使用运行时的功能,也就是说,根类相当于运行时系统的一个借口。
1.类和实例
NSObejct只有一个实例变量,就是Class类型的变量isa。isa用于标识实例对象属于哪个类对象。isa用于标识实例对象属于哪个类对象。因为isa决定着实例变量和类的关系,很重要,所以子类不可以修改isa的值。也不能直接通过访问isa来查询变量到底属于哪个类,而要通过实例方法class来完成查询。
NSObject的方法与其说是为自己定义的,不如说是为其子类和所有的实例对象而定义的。
-(Calss)class; 返回接受者所属类的类对象。
+(Class)class;返回类对象
-(id)self;返回接受者自身。是一个无任何实际动作但很有的方法。
-(Bool)isMemberOfClass:(Class)aClass; 判断消息接受者是不是参数aClass类的对象。
-(Bool)isKindOfClass:(Class)aClass判断消息接受者是否是aClass嘞或者是aClass类的子类的实例。这个和isMemberOfClass的区别在于当消息的接受者是aClass的子类的实例时也会返回YES;
-(Bool)isSubclassOfClass:(Class)aClass;判断消息接受者是不是参数aClass的子类或自身,如果是则返回YES
-(Class)superclass;返回消息接受者所在的父类的类对象;
+(Class)superclass;返回消息接受类的父类的类对象
2.实例对象的生成和释放
+(id)alloc;
-(void)dealloc;释放实例对象
-(oneway void)release;
-(id)retain;
-(id)autorelease;
-(NSUInterger)retainCount;
-(void)finalize;垃圾收集器在释放接受者对象之前会执行该finalize方法。
上面congdealloc到retainCount都是手动引用计数管理内存时调用的方法,使用ARC时不可用,finalize仅供垃圾回收有效时使用。
3.初始化
-(id)init
-(void)initialize;被用于类的初始化,也就是对类中共同使用的变量进行初始化,这个方法会在类收到第一个消息之前被自动调用,不能手动调用,而且只会被调用一次。
+(id)new;new是alloc和init 的组合。
4.对象的比较
-(Bool)isEqual:(id)anObject; 消息的接收者如果和参数anObject相等就返回YES
-(NSUinteger)hash;在把对象放入容器等的时候,返回系统内部用的散列值。【散列值相等的两个对象不一定相等,快速检索系统中一般都有散列表,OC的Foundation框架中也有用于计算散列的函数。数据存放的位置是由数据本身计算出来的散列值来决定的。及时内容相同的情况下,如果算出来的散列值不同,数据存放的位置也是不同的】
5.对象的内容描述
+(NSString *)description;返回一个NSSTring类型的字符串,表示消息接受者所属类的内容,通常都是这个类的类名。
-(NSString *)description;返回一个nsstring类型的字符串,表示消息接收者的实例对象的内容。通常是类名加id值,子类中也可以重新定义description的返回值。
6.关于消息发送机制
选择器和SEL类型
程序中的方法名(选择器)在编译后会被一个内部标识符所替代,这个内部标识符所对应的数据类型就是SEL类型。
OC为了能够在程序中操作编译后的选择器,定义了@selector()指令。通过使用@selector()指令就可以直接引用编译后的选择器。也可以生命SEL类型的变量。
选择器不同的情况下编译转化后生成的SEL类型的值也不一定想不同,相同的选择器所对应的SEL类型的值一定相同。
?
?