黑马程序员——ObjectiveC基础——类对象和SEL类型

来源:互联网 发布:域名多少钱一年 编辑:程序博客网 时间:2024/05/20 06:25

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

一、概述
类的本质:
类的本质其实是一个对象(类对象)
Person *p1 = [Person new];
p1是一个实例对象,而Person就是一个Class类型的类对象。
关于类对象:
1.类对象在程序运行时一直存在。
2.类对象是一种数据结构,存储类的基础信息:类的大小,类的名称,类的版本以及消息与函数的映射表等。
3.类对象所保存的信息在程序编译时确定,在第一次使用该类的时候被加载到内存中。
4.类对象代表类,类方法属于类对象。
5.如果消息接受者是类名,则类名代表类对象。
6.运行时,所有类的实例都由类对象生成,类对象会把实例的isa的值修改为自己的地址,每个实例的isa指针都指向该实例的类对象。
7.从类对象可以知道父类信息,可以相应的方法等。
8.类对象只能使用类方法,不可以使用对象方法。

二、类对象的获取和使用
1.类对象的获取
可以通过实例对象获取,也可以通过类名获取:
Animal *a = [Animal new];
Class c1 = [a class]; //通过对象名获取
Class c2 = [Animal class]; //通过类名获取
2.类对象的使用
可以用来创建实例对象,也可以用来调用类方法
Animal *a2 = [c1 new];//通过类对象创建实例对象
[c1 eat];//通过类对象调用类方法

示例代码:
Animal.h

#import <Foundation/Foundation.h>@interface Animal : NSObject-(void) test;+(void) test;@end

Animal.m

#import "Animal.h"@implementation Animal-(void) test{    NSLog(@"\n-执行的是对象方法");}+(void) test{    NSLog(@"\n+执行的是类方法");}@end

main.m

#import <Foundation/Foundation.h>#import "Animal.h"int main(int argc, const char * argv[]) {    @autoreleasepool {        Animal *a = [Animal new];        //类对象的获取        Class c1 = [a class];  //1.通过实例对象名获取类对象        Class c2 = [Animal class];  //2.通过类名获取类对象        NSLog(@"c1的地址:%p",c1);    //输出:c1的地址:0x1000011e0        NSLog(@"c2的地址:%p",c2);    //输出:c2的地址:0x1000011e0        //类方法的使用        Animal *a2 = [c1 new];  //1.通过类对象创建实例对象        [a2 test];  //输出:-执行的是对象方法        [c1 test];  //输出:+执行的是类方法  2.通过类对象调用类方法    }    return 0;}

三、SEL类型
SEL:全称selector,表示方法的存储位置。
寻找test方法的过程:
1.把test方法名包装成sel类型的数据。
2.根据SEL数据找到对应的方法地址。
3.根据方法地址调用相应方法。
注意:
1.寻找方法的过程中有缓存,第一次寻找的时候是一个一个对比寻找的,非常消耗性能,之后再用到该方法的时候就直接调用了。
2.SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去寻找对应的方法地址,找到方法地址之后就可以调用方法。这些都是运行时特性,发送消息就是发送SEL,然后根据SEL找到地址,调用方法。

实例代码:

#import <Foundation/Foundation.h>#import "Animal.h"int main(int argc, const char * argv[]) {    @autoreleasepool {        Animal *a = [Animal new];        //类对象的获取        Class c1 = [a class];  //通过实例对象名获取类对象                SEL s1 = @selector(test);        [a performSelector:s1];  //输出:-执行的是对象方法        [c1 performSelector:s1];  //输出:+执行的是类方法    }    return 0;}
0 0
原创粉丝点击