———————————————————————————————————————————

类的本质——类对象



一段代码:



#import <Foundation/Foundation.h>



@interface Person : NSObject

-(void)run;

+(void)run;

@end



@implementation Person

-(void)run

{

    NSLog(@"对象方法run!");

}



+(void)run

{

    NSLog(@"类方法run!");

}

@end



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

    @autoreleasepool {

        Person *p1=[Person new];

        [p1 run];

        

        [Person run];

        

        Person *p2=[Person new];

        

//        其实类也是一个对象,他也有他的类。比如Person其实就是一个对象,我们将这种对象称之为 类对象。而p1我们称之为类类型的实例对象,这两个是不一样,注意叫法区分。

//        类对象属于Class类型

        

//        类对象的获取方式:

//        ①通过实例对象获取:

        Class c1=[p1 class];//这两句话都是得到Dog这个类对象,需要注意的是,Class类声明类对象的时候,直接就是Class 变量名,变量名(如c1)前面是没有符号的(这是结构体,不是指针)

        Class c2=[p2 class];

//        我们打印检测一下c1、c2的地址如何

        NSLog(@"c1=%p",c1);//c1=0x100001200

        NSLog(@"c2=%p",c2);//c2=0x100001200

//        显然c1、c2虽为累类型不同的实例对象调用,但他们属于同一个累类型,所以说他们都是返回的Dog这个类对象的地址

        

//        当然我们还可以用%@的格式查看一下这个类类型的信息,显然输出的结果是  Person

        NSLog(@"%@",c1);//Person

        NSLog(@"%@",c2);//Person

        

//        ②通过类名获取

        Class c3=[Person class];

        NSLog(@"c3=%p",c3);

        

        NSLog(@"%@",c3);

    }

    return 0;

}





———————————————————————————————————————————

类对象的使用





一段代码:



#import <Foundation/Foundation.h>



@interface Person : NSObject

-(void)test;

+(void)test;

@end



@implementation Person

-(void)test

{

    NSLog(@"-test!");

}



+(void)test

{

    NSLog(@"+test!");

}

@end



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

    @autoreleasepool {

//        获取类对象

        Class c1=[Person class];//此时c1就等同于Person

        

//        类对象的使用:

//        ①使用类对象创建实例对象

        Person *p1=[c1 new];//这句话等同于 Person *p1=[Person new];

//        c1 *p1=[c1 new];//★但是我们却不能用这种方法进行创建实例对象,这一点一定要记住!

        [p1 test];//用实例对象p1调用对象方法test,调用成功说名创建实例对象成功

//        ②使用类对象调用类方法

        [c1 test];

    }

    return 0;

}







———————————————————————————————————————————

类对象的存储及SEL(理解)



在实例对象调用方法的时候,首先在类对象中进行判断(判断当前调用的方法的SEL   和   类的代码区里的SEL相比是不是一致),然后确定是不是调用。



下面介绍一下SEL:



★SEL全称selector表示方法的存储位置★



例如:



Person *p = [ [ Person alloc ] init ] ;

[ p test ] ;   //这里test是一个对象方法



寻找方法的过程:

①首先把test这个方法名包装成sel类型的数据

②根据sel数据找到对应的方法地址

③根据方法地址调用相应的方法

(注意一下,这个查找sel数据的过程有缓存,第一次找一个一个找非常的费时且非常耗性能,但是第二次就直接使用了)



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



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





一段代码并不完整(只是测试用的):



//        如果用SEL来调用test方法的话,我们可以这样做:

//        手动将test方法(对象方法)包装成 SEL 类型

        SEL s1=@selector(test);   //这里和Class声明类对象的时候是一样的,属于结构体类型

        [p1 performSelector:s1];

//        上面两句话,和  [p1 test]; 的作用是一模一样的

        [Person performSelector:s1];  //performSelector:s1就等同于test

//        当然这里也可以调用类方法

版权声明:本文为博主原创文章,未经博主允许不得转载。

最新文章

  1. Mybatis异常--java.lang.IllegalArgumentException: NO ENUM const class org.apache.ibatis.type.JdbcType.int
  2. 未能正确加载“RoslynPackage”包
  3. UILabel实现自适应高宽
  4. H - 放苹果
  5. [转]在Arcmap中加载互联网地图资源的4种方法
  6. Oracle varchar2 4000
  7. CKeditor 配置使用
  8. linux常用svn命令(转载)
  9. POJ训练计划1459_Power Network(网络流最大流/Dinic)
  10. 68、django之session与分页
  11. CSS Modules In Webpack
  12. [Windows Server]Windows Server turn off screen auto-lock to fit scheduled tasks(Error Code :0x4F7) / 关闭Windows Server的自动锁定来解决计划任务0x4F7错误
  13. 关于AI
  14. [No000015D]【李笑来 笔记整理】个人商业模式升级
  15. Trie树(转:http://blog.csdn.net/arhaiyun/article/details/11913501)
  16. POJ 1789 Truck History (Kruskal 最小生成树)
  17. vim学习笔记(10):vim命令大全
  18. VC++ 利用CreateFile、ReadFile和WriteFile实现CopyFile
  19. C语言初学
  20. js-TextArea的换行符处理

热门文章

  1. 转载 .net中的dll.refresh文件和pdb文件
  2. Linux web工程部署远程必备软件安装
  3. UI进阶 多线程
  4. IOS开发之 ---- 苹果系统代码汉字转拼音
  5. $_SERVER详细资料整理(转)
  6. 安卓模拟器Android SDK Manager 无法获取SDK列表的解决办法
  7. SQL Server 性能优化3 该指数(Index)保养
  8. js数组定义和获取其长度
  9. 详解 Objective-C 中的 Runtime
  10. Tomcat启动报错org.apache.coyote.AbstractProtocol.init Failed to initialize end point associated with ProtocolHandler [&quot;http-apr-8080&quot;]&rdquo;