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

类的本质——类对象



一段代码:



#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

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

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

Objective-C 【类对象及SEL存储方式】的更多相关文章

  1. (转)c++类的成员函数存储方式(是否属于类的对象)---一道面试题引发的思考

    昨天去面试一家公司,面试题中有一个题,自己没弄清楚,先记录如下: class D { public: void printA() { cout<<"printA"< ...

  2. JavaScript 创建类/对象的几种方式

    在JS中,创建对象(Create Object)并不完全是我们时常说的创建类对象,JS中的对象强调的是一种复合类型,JS中创建对象及对对象的访问是极其灵活的. JS对象是一种复合类型,它允许你通过变量 ...

  3. global对象,数据存储方式和检测,包装器对象等

    1.理解global对象 global对象是作为 window 对象的一部分实现的,我们无法通过代码访问到 global 对象. 我们平时在全局环境下定义的内容(变量,函数,常量等等)都是作为 glo ...

  4. Java反射获取类对象的三种方式

    package demo01; /* * 获取一个类的class文件对象的三种方式 * 1.对象获取 * 2.类名获取 * 3.Class类的静态方法获取 */ public class Reflec ...

  5. String类对象两种实例化方式比较

    第一种:直接赋值 String str =  "hello!" ; 在java中,有一个字符串常量池,对于这种直接赋值的,会直接写进常量池(常量池里面不存在其value,) 自JD ...

  6. JAVA反射机制教程-获取类对象

    1. 什么是类对象 类对象,就是用于描述这种类,都有什么属性,什么方法的 2. 获取类对象 获取类对象有3种方式(1). Class.forName(2). Hero.class(3). new He ...

  7. c/c++ 类成员变量,成员函数的存储方式,以及this指针在c++中的作用

    c/c++ 类成员变量,成员函数的存储方式,以及this指针在c++中的作用 c++不会像上图那样为每一个对象的成员变量和成员函数开辟内存空间, 而是像下图那样,只为每一个对象的成员变量开辟空间.成员 ...

  8. C++ 类的存储方式以及虚函数表

    一.C++成员函数在内存中的存储方式 用类去定义对象时,系统会为每一个对象分配存储空间.如果一个类包括了数据和函数,要分别为数据和函数的代码分配存储空间.按理说,如果用同一个类定义了10个对象,那么就 ...

  9. union 中可以存储的是不带构造函数的类对象

    union 中可以存储的是不带构造函数的类对象 否则不符合逻辑 为什么不符合逻辑?

随机推荐

  1. UVa 127 - "Accordian" Patience

    题目:52张扑克,从左到右在平面上排列,按着如下规则处理: 1.按照从左到右的顺序,如果一张牌和左边的第一张或者第三张匹配,就把它放到对应的牌上面. 2.如果可以移动到多个位置,移动到最左端的牌上面. ...

  2. Lexicographical Numbers

    Given an integer n, return 1 - n in lexicographical order. For example, given 13, return: [1,10,11,1 ...

  3. [一位菜鸟的COCOS-2D编程之路]打飞机中机种敌机和战机损毁时的爆炸效果

    1.第一步,添加爆炸动画 //添加玩家飞机飞行动画 id _playerFlyAction; id _playerBlowupAnimation; //战机爆炸动画 id _enemyBlowupAn ...

  4. RecyclerView全面解析

    写在前面 起深入浅出这名字的时候我是慎重又慎重的,生怕被人骂标题党,写的什么破玩意还敢说深入浅出.所以还是请大家不要抱着太高的期望,因为没有期望就没有失望,就像陈润说的,超预期嘛.全当看小说的心情来看 ...

  5. JQuery上传插件Uploadify API详解

    一.相关key值介绍uploader:uploadify.swf文件的相对路径,该swf文件是一个带有文字BROWSE的按钮,点击后淡出打开文件对话框,默认值:uploadify.swf. scrip ...

  6. mysql 在线修改表结构工具 gh-ost

    gh-ost使用测试: gh-ost -host='192.168.65.136' -user=root -password='' -database='haha' -chunk-size=10000 ...

  7. SCOM MP中的PowerShell脚本

    该脚本可在MP中运行 #param ($file,$threshold) #此处可定义file 和 threshold 参数,该参数可以从脚本外部接收 $threshold = 10 $file = ...

  8. android131 360 05 手势触摸滑动,sim卡,开机启动的广播,手机联系人,SharedPreferences,拦截短信

    安卓手势触摸滑动: package com.itheima52.mobilesafe.activity; import android.app.Activity; import android.con ...

  9. 重现PHP Core的调用栈

        以前, 我曾经介绍过如何通过PHP的Core文件获取信息:如何调试PHP的Core之获取基本信息, 对于调用参数这块, 当时介绍的获取方法比较复杂. 于是今天我为PHP 5.4的.gdbini ...

  10. Python 将文本转换成html的简单示例

    实例txt文件test_input.txt: Welcome to World Wide Spam. Inc. These are the corporate web pages of *World ...