Objective-C 【动态类型检测&响应方法】

时间:2021-11-06 22:58:48

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

动态类型检测



代码:



#import <Foundation/Foundation.h>



@interface Animal : NSObject

-(void)run;

-(void)abc;

@end



@implementation Animal

-(void)run

{

    NSLog(@"Animal run!");

}

-(void)abc

{

    NSLog(@"abc!");

}

@end



@interface Dog : Animal

-(void)run;

-(void)eat;

-(void)bark;

@end



@implementation Dog

-(void)run

{

    NSLog(@"Dog run!");

}

-(void)eat

{

    NSLog(@"Dog eat!");

}

-(void)bark

{

    NSLog(@"Dog bark!");

}

@end



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

    @autoreleasepool {

        

        //动态类型检测:

        //*******************************************************

        

//        1)判断某个对象是否是该类的实例对象,或者是其子类的实例对象(对象和类)

//        isKindOfClass使用格式:   [对象 isKindOfClass:类对象];

       

        Animal *ani=[Animal new];

        

        //BOOL isIstance=[ani isKindOfClass:[ani class]];

        BOOL isInstance=[ani isKindOfClass:[Animal class]];

        //上面两种写法都行,因为可以用 类类型的实例对象/类名 去调用类对象

        

        NSLog(@"isInstance = %d",isInstance);//输出是1(ani本来就是Animal的实例对象,自然为1)

        

        

        Dog *dog=[Dog new];

        BOOL isInstance1=[dog isKindOfClass:[Animal class]];

        NSLog(@"isIstance1 = %d",isInstance1);//输出是1(Dog是Animal的子类,dog是Dog的实例对象,自然为1)

        

        

        Person *p=[Person new];

        BOOL isInstance2=[p isKindOfClass:[Animal class]];

        NSLog(@"isInstance2 = %d",isInstance2);//输出是0(Person是无关的类,不是Animal的子类,p是Person的实例对象,所以为0)

        

        //*******************************************************

        

//        2)判断某个对象是否是该类的实例对象(单指这个类,不包括其子类)

        

//        isMemberOfClass使用格式:   [对象 isMemberOfClass:类对象];

       

        BOOL isInstance3=[ani isMemberOfClass:[Animal class]];

        NSLog(@"isInstance3 = %d",isInstance3);//输出是1(ani是Animal的实例对象,自然为1)



        BOOL isInstance4=[dog isMemberOfClass:[Animal class]];

        NSLog(@"isInstance4 = %d",isInstance4);//输出是0(dog是Dog的实例对象,Dog是Animal的子类,所以为0)

        

        //*******************************************************

        

//        3)判断某个类是不是另一个类的子类

        

//        isSubclassOfClass使用格式:    [类名/类对象 isSubclassOfClass:类对象];



        BOOL isInstance5=[Dog isSubclassOfClass:[Animal class]];

        NSLog(@"isInstance5 = %d",isInstance5);//输出为1(Dog是Animal的子类)



        BOOL isInstance6=[Animal isSubclassOfClass:[Dog class]];

        NSLog(@"isInstance6 = %d",isInstance6);//输出为0(Animal是Dog的父类)



        BOOL isInstance7=[[Dog class] isSubclassOfClass:[Animal class]];

        NSLog(@"isInstance7 = %d",isInstance7);//输出为1(这里注意前面可以写作类对象的形式)



//        BOOL isInstance8=[[Dog class] isSubclassOfClass:Animal];//这句话编译不会通过,因为后面Animal不是类对象的格式

        

        //*******************************************************

        

//        4)判断对象能否响应指定的方法

        

//        respondsToSelector使用格式:   [对象 respondsToSelector:方法的SEL];

//        BOOL isRespond1=ani respondsToSelector:<#(SEL)#>//这里显然参数传进来的应该是一个SEL的类型

//        我们一起来回顾一下SEL是什么。首先SEL表示方法的存储位置,我们一般先将方法包装为SEL类型,然后根据sel数据找到方法的地址,然后根据方法地址调用相应的方法。所以接下来我们应该这样处理:

        

        SEL s1=@selector(eat);//先将数据封装成SEL类型,获得方法的地址

        BOOL isRespond1=[dog respondsToSelector:s1];//eat是Dog里面的方法,dog是Dog的实例对象,所以可以访问

        NSLog(@"isRespond1 = %d",isRespond1);//输出为1

        

        SEL s2=@selector(bark);

        BOOL isRespond2=[ani respondsToSelector:s2];//ani是Animal的实例对象,但是bark是Dog的特有方法,所以说无法访问

        NSLog(@"isRespond = %d",isRespond2);//输出为0

        

//        所以说我们一般用实例对象调用方法之前,可以先作一个判断,如下:

//        if(isRespond1)

//        {

//            [dog eat];

//        }

//        else

//        {

//            NSLog(@"无法调用");

//        }

//        这样可以把错误扼杀在编译时,而不是到了运行的时候错误才发现。

        

        //*******************************************************

        

//        5)判断类能否调用(相应)指定的方法

        BOOL isRespond3=[Dog instancesRespondToSelector:s1];//s1是eat的SEL封装,eat是Dog的方法,所以可以调用

        NSLog(@"isRespond3 = %d",isRespond3);//输出为1

        

        BOOL isRespond4=[Animal instancesRespondToSelector:s1];//显然Animal不能调用其子类特有的方法

        NSLog(@"isRespond4 = %d",isRespond4);//输出为0

        

        SEL s3=@selector(abc);//abc方法是Animal中的

        BOOL isRespond5=[Dog instancesRespondToSelector:s3];//子类继承父类的abc方法,自然子类可以调用(★这里我要说明一点,如果你在父类中只写了abc方法的声明,而没有写实现的话,这里结果就是0,表示无法调用★)

        NSLog(@"isRespond5 = %d",isRespond5);//输出为1

        

        //*******************************************************

        

    }

    return 0;

}





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

响应方法(属于动态类型检测部分)

//响应方法(调用方法)

//1.响应无参方法

//2.响应有一个参数的方法

//3.响应有两个参数的方法(因为OC只提供了最多两个参数的响应方法)

#import <Foundation/Foundation.h>

@interface Animal : NSObject

-(void)run;

@end



@implementation Animal

-(void)run

{

    NSLog(@"Animal run!");

}

@end



@interface Dog : Animal

-(void)eat:(NSString *)foodName;

-(void)eat:(NSString *)foodName andDogName:(NSString *)dogName;

@end



@implementation Dog

-(void)eat:(NSString *)foodName

{

    NSLog(@"Dog eat %@",foodName);

}

-(void)eat:(NSString *)foodName andDogName:(NSString *)dogName

{

    NSLog(@"%@ eat %@",dogName,foodName);

}

@end



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

    @autoreleasepool {

//        以后调用方法,大都以这种形式调用

//        调用方法的时候,我们应该具备这样的思路,养成书写习惯:

//        ①首先调用方法得有 实例对象,所以要先创建实例对象

//        ②其次调用方法前要判断是否能调用,所以要有判断语句(对象是否能调用方法)

//        ③因为判定对象能调用方法的时候这个方法是以SEL的格式去调用的,所以先要将此方法转化成SEL的形式

//        ④然后判断结束后,返回值是1就调用,返回值是0就输出无法调用

//        ⑤最后调用 无参/有参 方法(本节所讲内容)

        //*******************************************************

        Animal *ani =[[Animal alloc]init];//①

        SEL s1=@selector(run);//③

        BOOL isRespond=[ani respondsToSelector:s1];//②

        if (isRespond) {//④

            [ani performSelector:s1];//⑤      实例对象调用无参方法

        }

        else

        {

            NSLog(@"无法调用!");

        }

        //*******************************************************

        Dog *dog=[[Dog alloc]init];

        SEL s2=@selector(eat:);//这里获取含多个参数的方法地址的时候,只写方法名即可

        BOOL isRespond2=[dog respondsToSelector:s2];

        if (isRespond2) {

            [dog performSelector:s2 withObject:@"coffee"];//实例对象调用含有一个参数的方法

        }

        else

        {

            NSLog(@"无法调用!");

        }

        //*******************************************************

        Dog *dog2=[[Dog alloc]init];

        SEL s3=@selector(eat:andDogName:);//只写方法名

        BOOL isRespond3=[dog respondsToSelector:s3];

        if (isRespond3) {

            [dog performSelector:s3 withObject:@"hotdog" withObject:@"bigmax"];//实例对象调用含两个参数的方法

        }

        else

        {

            NSLog(@"无法调用!");

        }

        //*******************************************************

    }

    return 0;

}





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

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

Objective-C 【动态类型检测&响应方法】的更多相关文章

  1. 六&period;OC基础--1&period; id和instancetype类型&comma;2&period;动态类型检测&comma;3&period;响应方法,构造方法&comma;4&period;重写构造方法&comma;5&period;自定义构造方法

    1. id和instancetype类型, id和instancetype类型区别: 1. id和instancetype都可以用来作为方法的返回值 2. id可以用来定义类型,instancetyp ...

  2. dynamic动态类型的扩展方法

    对于一个动态类型来说,你可以认为它包含任意成员,它们都能通过编译.但到了运行时,到底是否拥有这些成员,就真相大白了.如 dynamic test = ; Console.Write(test.Name ...

  3. OC 动态类型和静态类型

    多态 允许不同的类定义相同的方法 动态类型 程序直到执行时才能确定所属的类 静态类型 将一个变量定义为特定类的对象时,使用的是静态形态 将一个变量定义为特定类的对象时,使用的是静态类型,在编译的时候就 ...

  4. JS做类型检测到底有几种方法?看完本文就知道了!

    JS有很多数据类型,对于不同数据类型的识别和相互转换也是面试中的一个常考点,本文主要讲的就是类型转换和类型检测. 数据类型 JS中的数据类型主要分为两大类:原始类型(值类型)和引用类型.常见的数据类型 ...

  5. C&plus;&plus;基础知识:动态类型识别

    1.动态类型指的是基类指针所指向的对象的实际类型 2.C++中的多态根据实际的对象类型调用对应的虚函数(1)可以在基类中定义虚函数返回具体的类型信息(2)所有的派生类都必须实现类型相关的虚函数(3)每 ...

  6. JavaScript中类型检测

    文章首发: http://www.cnblogs.com/sprying/p/4349426.html 本文罗列了一般Js类型检测的方法,是构建Js知识体系的一小块,这篇文章是我很早之前总结的. 一. ...

  7. STUN&colon; NAT 类型检测方法

    STUN(Simple Transversal of UDP through NATs)[21]是RFC3489 规定的一种NAT 穿透方式,它采用辅助的方法探测NAT 的IP 和端口. STUN 的 ...

  8. 五&period;OC基础--1&period;多态&comma;2&period;类对象&comma;3&period;点语法&comma;4&period;&commat;property&amp&semi;&commat;synthesize&comma;5&period;动态类型&comma;内省&lpar;判断对象是否遵循特定的协议,以及是否可以响应特定的消息&rpar;

    五.OC基础--1.多态, 1. 多态概念,定义:多态就是某一类事物的多种形态: 表现形式: Animal *ani = [Dog new]; 多态条件:1.有继承关系 2.有方法的重写 2.多态代码 ...

  9. Asp&period;Net SignalR 使用记录 技术回炉重造-总纲 动态类型dynamic转换为特定类型T的方案 通过对象方法获取委托&lowbar;C&num;反射获取委托&lowbar; &period;net core入门-跨域访问配置

    Asp.Net SignalR 使用记录   工作上遇到一个推送消息的功能的实现.本着面向百度编程的思想.网上百度了一大堆.主要的实现方式是原生的WebSocket,和SignalR,再次写一个关于A ...

随机推荐

  1. 【Beta】第5&period;5次任务发布

    PM #100 日常管理&dev版宣传&设计报告管理后台. 后端 #101 完成收藏功能 完成管理员权限表的生成和接入(按位压缩权限表) 验收条件:收藏功能能够正常使用.能够区分常规用 ...

  2. 一些BOOTSTRAP的问题

    老师好,有几个点不是很明白,劳烦老师帮忙解惑 <1>不是特别清楚nav和navbar的区别,视频中用的是nav标签,而class则标明navbar,是不是这里的nav其实没有什么作用,而c ...

  3. jenkins配置及使用中出现的问题

    安装中遇到的问题: 1.linux中最好用普通用户安装tomcat和jenkins,用普通用户启动tomcat,否则jenkins工作空间不会在普通用户下,而线上自动发布部署时,是不允许用root用户 ...

  4. css 设置全屏背景图片

    <div id="div1"><img src="img.jpg" /></div> div#div1{ position: ...

  5. BZOJ 1002 轮状病毒 (基尔霍夫矩阵)

    题解:http://vfleaking.blog.163.com/blog/static/17480763420119685112649/ #include <iostream> #inc ...

  6. 动态BGP和静态BGP的含义与区别

    1.在华为云上选购虚拟机时,会让用户选择动态BGP还是静态BGP, 全动态BGP可根据设定的寻路协议第一时间自动优化网络结构,以保持客户使用的网络持续稳定.高效. 静态BGP中的网络结构发生变化,运营 ...

  7. Chrome不安装插件实现页面长截图

    1.打开需要截图的页面,按F12进入审查模式 或直接在页面右击鼠标右键-检查,打开如下窗口 2.在控制台中按下 ctrl+shift+p,弹出如下输入框  3.输入screen进行模糊查找,选择“Ca ...

  8. OpenGL中的光照技术(翻译)

    Lighting:https://www.evl.uic.edu/julian/cs488/2005-11-03/index.html 光照 OpenGL中的光照(Linghting)是很重要的,为什 ...

  9. &lbrack;Shell学习笔记&rsqb; 命令行下的高级网络工具cURL命令

    原文: http://www.1987.name/365.html Linux curl命令是一个利用URL规则在命令行下工作的文件传输工具.它支持文件的上传和下载,所以是综合传输工具,但按传统,习惯 ...

  10. supervisorctl unix&colon;&sol;&sol;&sol;var&sol;run&sol;supervisor&period;sock refused connection

    运行supervisorct 报如下错误 supervisorctl unix:///var/run/supervisor.sock refused connection 查看supervisord. ...