Objective-C 【类对象及SEL存储方式】
———————————————————————————————————————————
类的本质——类对象
一段代码:
#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存储方式】的更多相关文章
- (转)c++类的成员函数存储方式(是否属于类的对象)---一道面试题引发的思考
昨天去面试一家公司,面试题中有一个题,自己没弄清楚,先记录如下: class D { public: void printA() { cout<<"printA"< ...
- JavaScript 创建类/对象的几种方式
在JS中,创建对象(Create Object)并不完全是我们时常说的创建类对象,JS中的对象强调的是一种复合类型,JS中创建对象及对对象的访问是极其灵活的. JS对象是一种复合类型,它允许你通过变量 ...
- global对象,数据存储方式和检测,包装器对象等
1.理解global对象 global对象是作为 window 对象的一部分实现的,我们无法通过代码访问到 global 对象. 我们平时在全局环境下定义的内容(变量,函数,常量等等)都是作为 glo ...
- Java反射获取类对象的三种方式
package demo01; /* * 获取一个类的class文件对象的三种方式 * 1.对象获取 * 2.类名获取 * 3.Class类的静态方法获取 */ public class Reflec ...
- String类对象两种实例化方式比较
第一种:直接赋值 String str = "hello!" ; 在java中,有一个字符串常量池,对于这种直接赋值的,会直接写进常量池(常量池里面不存在其value,) 自JD ...
- JAVA反射机制教程-获取类对象
1. 什么是类对象 类对象,就是用于描述这种类,都有什么属性,什么方法的 2. 获取类对象 获取类对象有3种方式(1). Class.forName(2). Hero.class(3). new He ...
- c/c++ 类成员变量,成员函数的存储方式,以及this指针在c++中的作用
c/c++ 类成员变量,成员函数的存储方式,以及this指针在c++中的作用 c++不会像上图那样为每一个对象的成员变量和成员函数开辟内存空间, 而是像下图那样,只为每一个对象的成员变量开辟空间.成员 ...
- C++ 类的存储方式以及虚函数表
一.C++成员函数在内存中的存储方式 用类去定义对象时,系统会为每一个对象分配存储空间.如果一个类包括了数据和函数,要分别为数据和函数的代码分配存储空间.按理说,如果用同一个类定义了10个对象,那么就 ...
- union 中可以存储的是不带构造函数的类对象
union 中可以存储的是不带构造函数的类对象 否则不符合逻辑 为什么不符合逻辑?
随机推荐
- Runtime 10种用法
来源:haojingxue_iOS 链接:http://www.jianshu.com/p/3182646001d1 阅读了多篇运行时的文章,感觉都很不错,从几篇文章里面提取一些个人认为比较重要的,偏 ...
- Spring ApplicationContextAware获取上下文
一.ApplicationContextAware 用处 Spring 提供了ApplicationContextAware类,通过它可以获取所有bean上下文. 二.怎么用? ①.定义一个工具类,去 ...
- MySQL的安装——源码方式(实验环境下测试用,真实环境请忽略此文)
#虚拟机是最初的的系统,我们在虚拟机里安装scp [root@serv01 ~]# yum install /usr/bin/scp -y #安装过程略 #我们拷贝MySQL的源码包到目标机的/roo ...
- KeyTweak 键盘按键功能修改
最近一致再用ThinkPad S3,悲剧的是上翻页和下翻页竟然和方向键在一起,经常按错光标不知道去哪里了. 实在忍受不了,竟然有这样的软件,哈哈. KeyTweak,用起来太方便了
- ZOJ 3822 Domination 期望dp
Domination Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/showProblem ...
- iOS开发——高级技术&生成二维码
生成二维码 因为项目里需要新增个功能,该功能用到了二维码技术.于是我便查阅了资料,先学习了二维码的生成. 我们使用libqrencode库来生成二维码.下载地址http://download.cs ...
- java_jdbc_基本连接池
MyDataSource实现封装连接池,MyConnection实现connection类,通过代理模式相互调用 package cn.itcast; import java.sql.*; publi ...
- SVN 之 去掉SVN管理标记
当项目不需要SVN标志的时候, 方式一:很多人设置Windows显示隐藏文件,然后将项目中的所有.svn文件删除,这种方法是最笨的方法. 方式二:通过注册表方式 [1]新建一个文本文件.文本的内容为: ...
- oracle11g密码大小写敏感问题
密码大小写敏感是Oracle 11g数据库默认的一个新特性,数据库配置助手(DBCA)在创建数据库期间允许你将这个设置返回到11g以前的功能. SEC_CASE_SENSITIVE_LOGON初始化参 ...
- ios知识点
在controller中加载plist数据 1,设置属性NSArray 或可变数组NSMutableArray @property(nonatomic,strong)NSArray *message; ...