[玩玩Objective-C]之动态绑定

来源:互联网 发布:养生壶 知乎 skg和北鼎 编辑:程序博客网 时间:2024/06/17 01:46

前些日子买了台MacBook Air ,用了一段时间之后发现没什么好玩的,于是乎,程序猿的天性使然,我就想在Mac上写点小程序玩玩,然后就在网上买了两本书来研究,觉得有所收获后,就写成博客分享给大家。OC其实很简单,只是比起传统的类C的面向对象语言,如Java,C#等,语法确实有些奇怪。转载请注明出处:朱登凯的专栏 http://blog.csdn.net/daguanjia11

本篇文章和大家一起学习Objective-C中的动态绑定。

动态类型

动态绑定的主体是动态类型。动态类型,也就是id类型,可以用来存储任何类型的对象。使用方法如下:

id obj=[[Person alloc] init];

上面的例子中,obj对象本来是Person类型,却被赋值给了id类型。

动态绑定

下面来看一个动态绑定的例子。首先新建两个类,Person类和Dog累。

Person类的声明部分和实现部分

#import <Foundation/Foundation.h>@interface Person : NSObject-(void) sayHello;-(void) work;@end
#import "Person.h"@implementation Person-(void) sayHello{    NSLog(@"Hello,I am a Person");}-(void) work{    NSLog(@"I love working...");}@end

Dog类的声明部分和实现部分

#import <Foundation/Foundation.h>@interface Dog : NSObject-(void) sayHello;@end
#import "Dog.h"@implementation Dog-(void) sayHello{    NSLog(@"Hello,I am a Dog");}@end

下面就是所谓的动态绑定

#import <Foundation/Foundation.h>#import "Person.h"#import "Dog.h"int main(int argc, const char * argv[]) {    @autoreleasepool {        id obj=[[Person alloc] init];        [obj sayHello];        [obj work];        obj=[[Dog alloc] init];        [obj sayHello];        //下面这个方法调用后有惊喜哦!        //[obj work];    }    return 0;}

先后给obj赋不同的值,调用[obj sayHello];得到的结果确实不一样的。
在面向对象的特性中,这叫多态。

判断动态类型的对象是否具有某个方法

在上面的Main 函数中注释掉的//[obj work]; 中,如果不注释掉的话,运行时会抛出一个异常,并且导致程序中断。这也就意味着,动态类型虽然用着很爽,什么类型的对象都可以声明为id类型,但是用的时候需要小心,如果搞错了,调用了一个该对象不包含的方法的话,程序会抛出异常的。
一个比较有效的办法就是,对动态类型的对象调用方法时,先判断该类型是否响应这个方法。如何实现呢?
下面是修改后的Main方法

#import <Foundation/Foundation.h>#import "Person.h"#import "Dog.h"int main(int argc, const char * argv[]) {    @autoreleasepool {        SEL sayHelloSEL,workSEL;        sayHelloSEL= @selector(sayHello);        workSEL=@selector(work);        id obj=[[Person alloc] init];        //如果该对象具有sayHello方法        if([obj respondsToSelector:sayHelloSEL])        {            [obj sayHello];        }        //如果该对象具有work方法        if([obj respondsToSelector:workSEL])        {            [obj work];        }        obj=[[Dog alloc] init];        //如果该对象具有sayHello方法        if([obj respondsToSelector:sayHelloSEL])//会返回false        {            [obj sayHello];        }        //如果该对象具有work方法        if([obj respondsToSelector:workSEL])        {            [obj work];        }    }    return 0;}

首先,我通过@selector命令,生成一个SEL对象,这个对象表示一个方法,然后,[obj respondsToSelector:sayHelloSEL]能够判断出obj对象是否具有sayHelloSEL所对应的方法。sayHello这个方法比较简单,没有参数,如果有参数或者多个参数的方法,如何生成SEL对象呢?举两个例子吧

-(void) eatFood:(NSString*) foodName;-(void) setName:(NSString *)name andAge:(int) age;

上面的两个方法,如何调用@selector生成SEL对象呢

SEL sel1=@selector(eatFood:);SEL sel2=@selector(setName:andAge:);

注意一个原则,有几个参数,就有几个冒号,没有参数就没有冒号。

其它处理动态类型的方法

关于动态类型判断的方法,除了responseToSelector以外,还有很多,比如,isKindOfClass,isSubclassOfClass,confirmsToProtocol等,篇幅有限,本篇的介绍到此为止,如果对以上几个方法感兴趣,请关注后续的博客。

1 0
原创粉丝点击