当时学习Object C的时被人鄙视了一顿,说使用.NET的思想来学Object C就是狗屎;不过也挺感谢这位仁兄的,这让我学习的时候更加的谨慎。今天的学习笔记主要记录Object C中的动态类型相关内容。

  首先还是和.NET先对比一下,.NET中存在一个关键字var ,这个估计用过.NET的都知道,除非没有接触过3.0以上版本的。在.NET中能够使用var来声明任何类型的局部变量,负责告诉编译器,该变量需要根据初始化表达式来推断变量的类型,而且只能是局部变量.但是这里要注意的时var 并不是一个新的类型,只是一个关键字而已,在定义参数和返回值的时候都不能使用var.

  在.net中还有一个类型dynamic,表示变量的类型在运行时决定,也就是在运行此代码的时候才去校验类型是否符合等,如果类型不符则会抛出异常。而var则会在编译的过程就能够发现类型是否准确。

  在这里我们要说Object C中的id类型 和 var 以及 dynamic 有什么区别?

  一. Object C中的id类型

    在Objective-C 中,id 类型是一个独特的数据类型。在概念上可以转换为任何数据类型。换句话说,id 类型的变量可以存放任何数据类型的对象。在内部处理上,这种类型被定义为指向对象的指针,实际上是一个指向这种对象的实例变量的指针。

    先看一段代码了解一下id类型的时候:

id stu=[[Student alloc] init];
[stu eat]; id per=[[Person alloc] init];
[per eat];

    以上代码分别用创建了两个类Student 和 Person的实例,类型都是使用的id,并且调用了其相应的方法,成功运行。

  二. 动态判断

    在Object C中如何判断某个类实例是否是某个类的子类,某个类中是否包含某个方法。这个要求似乎和.NET中的反射有点类似,的确在Object中同样提供了类似的方法来动态判断。

    我们先定义一个父类:

#import <Foundation/Foundation.h>

@interface Person : NSObject{
NSString *name;
int age;
NSString *address;
}
@property (nonatomic,retain) NSString *name;
@property (nonatomic,assign) int age;
@property (nonatomic,retain) NSString *address; -(void) eat; -(void) speak; -(void) write; -(Person *) getPerson; -(id) getString; +(void) Info; @end ----------------------------------------------------------------
#import "Person.h" @implementation Person @synthesize name;
@synthesize age;
@synthesize address; -(void) eat{
NSLog(@"Person.eat()");
} -(void) speak{
NSLog(@"Person.speak()");
} -(void) write{
NSLog(@"Person.write()");
} -(Person *) getPerson{
Person *p=[[Person alloc] init];
p.name=@"li";
p.age=;
p.address=@"上海";
return p;
} -(id) getString{
Person *p=[[Person alloc] init];
p.name=@"lin";
p.age=;
p.address=@"北京";
return p;
} +(void) Info{
NSLog(@"Person.Info");
} @end

Person 类

    然后定义一个子类,用于继承Person类。

#import "Student.h"

@implementation Student

@end

Student 类

    Student类继承了Person类,说明Student类拥有了Person类的所有方法和属性

    (1) isMemberOfClass 用于判断是否是某个类的实例

bool flag1=[stu isMemberOfClass:[Student class]];
NSLog(@"%d",flag1);
bool flag2=[stu isMemberOfClass:[Person class]];
NSLog(@"%d",flag2);

    上面的代码 flag1 为yes,而flag2为no,说明stu是Student类的实例,Student为Person的子类,但是不能判断为Person的实例。

    (2) isKindOfClass 判断是否为某个类的实例或者某个类子类的实例

bool flag1=[stu isKindOfClass:[Student class]];
NSLog(@"%d",flag1);
bool flag2=[stu isKindOfClass:[Person class]];
NSLog(@"%d",flag2);

    因为Student是Person的子类,所以上面flag1,flag2 的都为YES

    (3) respondsToSelector 用于判断某个类型或者对象是否有能力回应(调用)指定的方法

bool flag3=[per respondsToSelector:@selector(eat)];
NSLog(@"%d",flag3); bool flag4=[stu respondsToSelector:@selector(eat)];
NSLog(@"%d",flag4); bool flag5=[per respondsToSelector:@selector(Info)];
NSLog(@"%d",flag5); bool flag6=[Person respondsToSelector:@selector(Info)];
NSLog(@"%d",flag6);

respondsToSelector 测试代码

    上面的代码测试输出结果如下:

-- ::09.778 ObjectSelect[:]
-- ::09.778 ObjectSelect[:]
-- ::09.778 ObjectSelect[:]
-- ::09.779 ObjectSelect[:]

    第一个和第二个方法的调用都返回1,说明其有能力回应(调用)方法eat, 关键看第三个和第四个方法的调用,返回0,1 说明实例和对象的调用是不一样的,而Info方法是一个全局方法 ,用 "+" 标识的方法就是全局方法,相当于静态方法。第3个方法是使用实例来调用的返回0,说明对象实例是没有能力调用静态方法的。

    (4) instancesRespondToSelector 用于判断某个对象的实例是否有能力回应(调用)指定的方法

        bool flag7=[Person instancesRespondToSelector:@selector(eat)];
NSLog(@"%d",flag7);
bool flag8=[Person instancesRespondToSelector:@selector(Info)];
NSLog(@"%d",flag8);

    上面的测试代码输出结果如下:

-- ::04.700 ObjectSelect[:]
-- ::04.700 ObjectSelect[:]

    第一个方法调用返回1,说明Person的实例可以调用eat方法,第二个方法返回0,说明Person的实例不可以调用Info方法。

  三. 如何动态调用方法

    上面已经说到了,任何一个对象的实例我们都可以使用id来指向其地址,这是一个动态的类型那么如何调用其具体的方法。

[stu performSelector:@selector(eat)];
[Person performSelector:@selector(Info)];

    使用performSelector 方法可以动态的调用其方法,如果是实例方法则调用的需要使用对象实例,而调用静态方法这需要使用对象本身。

    上面的办法调用都是没有参数的,那么如何调用有输入参数的方法呢?

[stu performSelector:@selector(speak:) withObject:@"ddddd"];

[stu performSelector:@selector(write:andAge:) withObject:@"fasdfadaf" withObject:@""];

    使用withObject 来填充参数.但是这个方法的调用有点不足的地方,如果有多个参数输入参数就有问题。 这个地方还没有完全没有弄清楚,有待后续研究。如果真的涉及到多个参数,那么可以使用对象封装好这些参数或者将参数存入一个集合中传递输入。

  四. 总结

    这篇主要讲到了动态类型id,以及其如何使用。还有关于类的动态判断以及选择器。但都只是比较粗略的介绍了,后面的学习中继续深入研究。

    本文开头的时候对比了.NET 中的var , dynamic 。 从上面的文章介绍,那么Object C中的id 和 .NET中的哪个关键字比较像,个人的学习体会和dynamic比较类似,如有不对的正确的地方请高手斧正!

  补充说明文章: Object C学习笔记18-SEL,@ selector,Class,@class

  本文到此结束,请高手勿喷,菜鸟的学习需要鼓励!

Object C学习笔记17-动态判断和选择器的更多相关文章

  1. Object C学习笔记18-SEL,@ selector,Class,@class

    本章是对上一章<<Object C学习笔记17-动态判断和选择器>>的一点补充,所以比较简单点. 一. SEL 类型 在上一篇介绍了几个方法,都只是介绍了其使用方式但是没有具体 ...

  2. Object C学习笔记24-关键字总结

    学习Object C也有段时间了,学习的过程中涉及到了很多Object C中的关键字,本文总结一下所涉及到的关键字以及基本语法. 1.  #import #import <> 从syste ...

  3. Web Service学习笔记:动态调用WebService

    原文:Web Service学习笔记:动态调用WebService 多数时候我们通过 "添加 Web 引用..." 创建客户端代理类的方式调用WebService,但在某些情况下我 ...

  4. golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍

    golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍 go语言爬虫框架:gocolly/colly,goquery,colly,chrom ...

  5. Object C学习笔记24-关键字总结(转)

    学习Object C也有段时间了,学习的过程中涉及到了很多Object C中的关键字,本文总结一下所涉及到的关键字以及基本语法. 1.  #import #import <> 从syste ...

  6. MyBatis:学习笔记(4)——动态SQL

    MyBatis:学习笔记(4)——动态SQL 如果使用JDBC或者其他框架,很多时候需要你根据需求手动拼装SQL语句,这是一件非常麻烦的事情.MyBatis提供了对SQL语句动态的组装能力,而且他只有 ...

  7. SpringBoot学习笔记:动态数据源切换

    SpringBoot学习笔记:动态数据源切换 数据源 Java的javax.sql.DataSource接口提供了一种处理数据库连接的标准方法.通常,DataSource使用URL和一些凭据来建立数据 ...

  8. Object C学习笔记22-#define 用法

    上一篇讲到了typedef 关键字的使用,可以参考文章 Object C 学习笔记--typedef用法 .而在c中还有另外一个很重要的关键字#define. 一. #define 简介 在C中利用预 ...

  9. Object C学习笔记21-typedef用法

    在上一章的学习过程中遇到了一个关键字typedef,这个关键字是C语言中的关键字,因为Object C是C的扩展同样也是支持typedef的. 一. 基本作用 typedef是C中的关键字,它的主要作 ...

随机推荐

  1. 关于macOS Sierra无法使用gdb进行调试的解决方案

    1.对gdb进行签名,签名过程详见:http://jingyan.baidu.com/article/d169e1864dc24d436611d839.html: 2.重新启动系统,同时按住键盘上的c ...

  2. Debian

    一.简介 https://zh.wikipedia.org/wiki/Debian 二.下载 https://www.debian.org/ 三.配置 1)挂载iso镜像 mount /dev/cdr ...

  3. 《精解Windows 10》

    <精解Windows 10>全面深入讲解Windows 10操作系统的使用方法.本书共计14章内容.第一章简述Windows 10操作系统的一些变革:第二章介绍Modern 2.0界面的体 ...

  4. puppet学习笔记(二)

    在puppet安装完成之后我们就可以动手开始第一个puppet实验了,此实验就以批量推送文件为例吧. 1.获取module路径 这里的module就是指一个模块,可以把puppet想象成一个个项目的部 ...

  5. 基于元数据的ETL系统

     从努力到选择  从实现到设计 从部分到整体 以下是我对DW design的一些想法 下次使用C#来实现一下   ETL中Source 的信息       数据提供形式:DB(ORACLE SQLSE ...

  6. WEB安全--业务安全漏洞

    0x00 索引说明 在OWASP的分享,关于业务安全的漏洞检测模型. 0x01 身份认证安全 1 暴力破解 在没有验证码限制或者一次验证码可以多次使用的地方,使用已知用户对密码进行暴力破解或者用一个通 ...

  7. 怎样快速学会ZBrush 中的移动笔刷的运用

    本篇视频教程,进入ZBrush®最精彩章节,雕刻前我们需要认识的雕刻工具-笔刷.zbrush自带了多种笔刷供大家选择和使用,掌握和用好这些笔刷将让我们的雕刻工作更加自由.本课的内容将主要向大家介绍最基 ...

  8. Rem实现自适应初体验

    第一次做移动端的页面,遇到的第一个问题就是移动端的轮播图.其实轮播图的插件有很多,但是完全满足需求的并不容易找. 需求: 1.实现基本的触屏轮播图效果 2.传入非标准比例的图片,可以自动平铺(有时候图 ...

  9. UESTC 918 WHITE ALBUM --生成树变形

    最小生成树变形. 题目已经说得很清楚,要求到达每个房间,只需求一个最小生成树,这时边权和一定是最小的,并且那k个房间一定与所有点都有通路,即一定都可以逃脱. 但是有可能当所有点都有了该去的安全房间以后 ...

  10. npm install时报错 npm ERR!Windows_NT 6.1.7601

    解决办法:先设置代理为空 npm config set proxy null, 然后再npm install cnpm -g --registry=https://registry.npm.taoba ...