有关类的问题

 引入动态类型后,问题随之而来。比如说在运行时如何判断一个对象是某种类型,一个对象是否支持某方法,一个对象是否是某类或是其子类的成员。幸运的是,NSObject类为我们提供了一些方法用于处理这类问题,要使用这些方法,我们需要一些铺垫。

 
 
  1. -(BOOL) isKindOf:class-object(判断对象是否是class-object或其子类的成员)  
  2. -(BOOL) isMenberOfClass:class-object(判断对象是否是class-object的成员)  
  3. -(BOOL) respondsToSelector:selector(判断对象是否能够响应selector所指定的方法)  
  4. +(BOOL) instancesRespondToSelector:selector(判断指定的类实例是否能响应selector所指定的方法)  
  5. +(BOOL) isSubclassOfClass:class-object(判断对象是否是指定类的子类)  
  6. -(id) performSelector:selector(应用selector指定的方法)  
  7. -(id) performSelector:selector withObject:object(应用selector指定的方法,传递参数object)  
  8.  -(id) performSelector:selector withObject:object1 withObject:object2(应用selector指定的方法,传递参数object1和object2) 

首先介绍class方法,看下面的示例代码: 

C代码   收藏代码
  1. #import "Square.h"  
  2.   
  3. int main(int argc, const char * argv[])  
  4. {  
  5.   
  6.     @autoreleasepool {  
  7.         Rectangle *rect=[Rectangle new];  
  8.         Class cls=[rect class];  
  9.         NSLog(@"%@",cls);  
  10.         NSLog(@"%@",[Square class]);  
  11.     }  
  12.     return 0;  
  13. }  

    首先我们创建了一个Rectangle对象rect,之后对rect调用class方法返回一个Class类型的对象,然后打印这个cls对象的内容。而下面我们对Square类直接调用class方法,也能返回Class对象,那么编译运行,我们得到如下结果: 

  


    我们可以看到通过class方法我们可以获取当前对象的类型,使用类名来调用通常也是为了返回这个类型的对象,他们都是Class类型的对象。那么我们知道class方法的用处后就可以用于判断了,比如下面的代码: 
C代码   收藏代码
  1. #import "Square.h"  
  2.   
  3. int main(int argc, const char * argv[])  
  4. {  
  5.   
  6.     @autoreleasepool {  
  7.         Rectangle *rect=[Rectangle new];  
  8.         Square *square=[Square new];  
  9.         Rectangle *rectangle=[Rectangle new];  
  10.           
  11.         if([rect class]==[rectangle class]){  
  12.             NSLog(@"rect & rectangle is the same class");  
  13.         }  
  14.         if([square class]==[rect class]){  
  15.             NSLog(@"square & rect is the same class");  
  16.         }  
  17.     }  
  18.     return 0;  
  19. }  

    那么我们很容易就能与基础该程序的效果,请看下图所示: 

 
 



    下面介绍@selector指令,该指令用于一个方法名,比如@selector (alloc),它的返回值是SEL类型,这个指令所获取的SEL类型结果也是用于动态类型的一些方法的,这里我们仅仅有个感性认识即可,那么看下面的代码: 
C代码   收藏代码
  1. #import "Square.h"  
  2.   
  3. int main(int argc, const char * argv[])  
  4. {  
  5.   
  6.     @autoreleasepool {  
  7.         SEL sel=@selector(setSide);  
  8.           
  9.         NSLog(@"SEL=%@",NSStringFromSelector(sel));  
  10.     }  
  11.     return 0;  
  12. }  

    这里我们需要将SEL结果转换成NSString类型,那么编译运行,我们会得到如下结果: 

 
 



    那么在后面处理动态类型的方法中,我们会看到@selector指令的具体用途。参考下面的程序: 
C代码   收藏代码
  1. #import "Square.h"  
  2.   
  3. int main(int argc, const char * argv[])  
  4. {  
  5.   
  6.     @autoreleasepool {  
  7.         Square *square=[Square new];  
  8.           
  9.         NSLog(@"%@",[square isMemberOfClass:[Square class]]?@"YES":@"NO");  
  10.         NSLog(@"%@",[square isMemberOfClass:[Rectangle class]]?@"YES":@"NO");  
  11.         NSLog(@"%@",[square isMemberOfClass:[NSObject class]]?@"YES":@"NO");  
  12.           
  13.         NSLog(@"%@",[square isKindOfClass:[Square class]]?@"YES":@"NO");  
  14.         NSLog(@"%@",[square isKindOfClass:[Rectangle class]]?@"YES":@"NO");  
  15.         NSLog(@"%@",[square isKindOfClass:[NSObject class]]?@"YES":@"NO");  
  16.           
  17.         NSLog(@"%@",[square respondsToSelector:@selector(setSide:)]?@"YES":@"NO");  
  18.         NSLog(@"%@",[square respondsToSelector:@selector(setWidth:andHeight:)]?@"YES":@"NO");  
  19.         NSLog(@"%@",[Square respondsToSelector:@selector(alloc)]?@"YES":@"NO");  
  20.           
  21.         NSLog(@"%@",[Rectangle instanceRespondToSelector:@selector(setSide:)]?@"YES":@"NO");  
  22.         NSLog(@"%@",[Square instanceRespondToSelector:@selector(setSide:)]?@"YES":@"NO");  
  23.           
  24.         NSLog(@"%@",[Square isSubclassOfClass:[Rectangle class]]?@"YES":@"NO");  
  25.     }  
  26.     return 0;  
  27. }  

    我们先来看运行结果: 

 
 



    我们逐行来解释一下这个程序,isMemberOfClass : class方法用于判断对象是不是class的成员,返回值为BOOL类型,那么这里我们使用三目运算符来获取BOOL表达式的结果,NSString也是id类型的一种,那么我们使用%@来表示。很显然square对象是Square类的一个成员,而不是Rectangle类和NSObject类的成员。 
    isKindOfClass: class方法用于判断对象是不是class类或其子类的成员。显然square对象是Square类的成员,是Rectangle类和NSObject类的子类成员。 
    respondsToSelector : selector方法用于判断对象是否可以响应@selector提供的方法,那么直接看上面的结果即可,不用多说了。instanceRespondToSelector : selector方法用于判断指定的实例能否响应@selector提供的方法,那么直接看结果就行了。 
    这些方法我们仅仅有个感性认识即可,等后续内容使用到了再做深入了解。 
    我们知道运用动态类型时在程序执行过程中可能会出现异常,那么如何来处理异常呢?Objective-C中引入@try块儿来处理异常,异常处理在@catch块中进行。我们来看下面的代码: 
C代码   收藏代码
  1. #import "Fraction.h"  
  2. #import "Complex.h"  
  3.   
  4. int main(int argc, const char * argv[])  
  5. {  
  6.     @autoreleasepool {  
  7.         id result;  
  8.           
  9.         id fractionA = [Fraction new];  
  10.           
  11.         [fractionA setTo:1 over:3];  
  12.   
  13.         id complexA=[Complex new];  
  14.           
  15.         [complexA setReal:10.0 andImaginary:2.3];  
  16.           
  17.         @try {  
  18.             result=[fractionA add:complexA];  
  19.         }  
  20.         @catch (NSException *exception) {  
  21.             NSLog(@"Caught: %@%@",exception.name,exception.reason);  
  22.         }  
  23.         @finally {  
  24.             NSLog(@"In finally");  
  25.         }  
  26.   
  27.     }  
  28.     return 0;  
  29. }  

    代码使用的是我们分数和复数的项目,那么为了引发异常,我们将分数类和复数类都使用id类型来表示,显然编译器不会报错,然后我们对两个不同的对象使用add方法,这显然是不可以的,那么将代码放入@try块中,在@catch块中进行异常处理,这里我们仅仅是打印一些异常信息。在@finally块中编写不论异常是否发生,都要执行的代码,那么编译运行后,我们得到如下结果: 

 


    之后我们修改代码,不会出现异常时是这样的情况: 
C代码   收藏代码
  1. #import "Fraction.h"  
  2. #import "Complex.h"  
  3.   
  4. int main(int argc, const char * argv[])  
  5. {  
  6.     @autoreleasepool {  
  7.         id result;  
  8.           
  9.         id fractionA = [Fraction new];  
  10.           
  11.         [fractionA setTo:1 over:3];  
  12.   
  13.         id fractionB=[Fraction new];  
  14.           
  15.         [fractionB setTo:10 over:18];  
  16.           
  17.         @try {  
  18.             result=[fractionA add:fractionB];  
  19.         }  
  20.         @catch (NSException *exception) {  
  21.             NSLog(@"Caught: %@%@",exception.name,exception.reason);  
  22.         }  
  23.         @finally {  
  24.             NSLog(@"In finally");  
  25.         }  
  26.   
  27.     }  
  28.     return 0;  
  29. }  

    此时代码不会出错了,那么编译运行就得到了如下结果: 

 


    可以看到@finally块中的语句无论异常是否发生,都会执行。所以它常用来进行连接的关闭等操作。如果想主动抛异常,还可以使用@throw指令来进行,这就是更高级内容了,暂时先不涉及。因为异常处理的开销很大,特别是移动设备对资源占用很敏感,所以非必要,请不要使用异常处理。 

转自:http://sarin.iteye.com/blog/1820539

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
若你有关于财经计算机问题的具体问题,以下是一些查询方法可以帮助你找到相关答案: 1. 搜索引擎:使用搜索引擎如Google、百度等,在搜索框中输入你的问题关键词,例如 "财经计算机应用"、"财经领域的机器学习算法"等。搜索引擎会给出相关的网页链接,你可以点击链接进一步了解相关知识。 2. 在线论坛和社区:参与财经计算机相关的在线论坛和社区,如知乎、Quora、CSDN等。在这些平台上,你可以提问并与其他专业人士和爱好者交流,获取他们的观点和建议。 3. 学术论文和研究报告:使用学术搜索引擎如Google学术、百度学术等,搜索关于财经计算机的学术论文和研究报告。这些论文和报告通常包含了具体的研究方法和应用案例,可以帮助你深入了解财经计算机领域的相关问题。 4. 在线课程和教程:许多在线教育平台如Coursera、edX等提供与财经计算机相关的课程和教程。通过参加这些课程,你可以系统地学习财经计算机的基础知识和应用技巧。 5. 专业书籍和期刊:查找与财经计算机相关的专业书籍和期刊,如《金融计算机模型与算法》、《金融工程学报》等。这些书籍和期刊通常包含了深入的理论和实践内容,适合深度学习和研究财经计算机问题。 无论使用哪种查询方法,都建议多方面查阅不同来源的资料,以获得全面和准确的信息。此外,对于较为专业和复杂的问题,也可以寻求专业人士的意见和建议。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值