`

Objective-C语法之动态类型(isKindOfClass, isMemberOfClass,id)等 .

    博客分类:
  • oc
阅读更多
对象在运行时获取其类型的能力称为内省。内省可以有多种方法实现。

判断对象类型

-(BOOL) isKindOfClass: classObj判断是否是这个类或者这个类的子类的实例

-(BOOL) isMemberOfClass: classObj 判断是否是这个类的实例

ps:本篇新建的类主要用于熟悉本篇内容设计,未考虑内存管理因素。

我们试试这两个方法的使用。




1、新建Person类继承NSObject,新建Teacher类继承Person
1.1、新建Person类
#import <Foundation/Foundation.h>

@interface Person : NSObject
{
    NSString *name;
}
-(void)setName:(NSString*)n;

@end


#import "Person.h"

@implementation Person
-(void)setName:(NSString *)n
{
    name = n;
}

@end



1.2新建Teacher类
#import "Person.h"

@interface Teacher : Person

-(void)teach;

@end

#import "Teacher.h"

@implementation Teacher
-(void)teach
{
    NSLog(@"我教数学");
}
@end


1.3 我们先实验下isMemberOfClass方法。
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    Person *person = [[Person alloc] init];
    Teacher *teacher = [[Teacher alloc] init];
    
    //YES
    if ([teacher isMemberOfClass:[Teacher class]]) {
         NSLog(@"teacher Teacher类的成员");
    }
    //NO
    if ([teacher isMemberOfClass:[Person class]]) {
        NSLog(@"teacher Person类的成员");
    }
    //NO
    if ([teacher isMemberOfClass:[NSObject class]]) {
        NSLog(@"teacher NSObject类的成员");
    }
    [person release];
    [teacher release];
    [pool release];


打印结果:

2012-07-04 14:23:07.965 ObjectiveCTest[2460:f803] teacher Teacher类的成员

只有第一个判断打印出来,isMemberOfClass判断是否是属于这类的实例,是否跟父类有关系他不管。



1.4 isKindOfClass方法
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    Person *person = [[Person alloc] init];
    Teacher *teacher = [[Teacher alloc] init];
    
    //YES
    if ([teacher isKindOfClass:[Teacher class]]) {
        NSLog(@"teacher 是 Teacher类或Teacher的子类");
    }
    //YES
    if ([teacher isKindOfClass:[Person class]]) {
        NSLog(@"teacher 是 Person类或Person的子类");
    }
    //YES
    if ([teacher isKindOfClass:[NSObject class]]) {
        NSLog(@"teacher 是 NSObject类或NSObject的子类");
    }
    [person release];
    [teacher release];
    [pool release];


2012-07-04 14:34:17.315 ObjectiveCTest[2595:f803] teacher 是 Teacher类或Teacher的子类

2012-07-04 14:34:17.316 ObjectiveCTest[2595:f803] teacher 是 Person类或Person的子类

2012-07-04 14:34:17.316 ObjectiveCTest[2595:f803] teacher 是 NSObject类或NSObject的子类

三个结果都打印出来了。





2、
-(BOOL) respondsToSelector: selector 判读实例是否有这样方法

+(BOOL) instancesRespondToSelector:  判断类是否有这个方法。此方法是类方法,不能用在类的对象

2.1 respondsToSelector的使用
这里不写对象的创建和释放了,参考上面的代码

    // YES
    if ( [teacher respondsToSelector: @selector( setName: )] == YES ) {
        NSLog(@"teacher responds to setSize: method" );
    }
    
    // NO
    if ( [teacher respondsToSelector: @selector( abcde )] == YES ) {
        NSLog(@"teacher responds to nonExistant method" );
    }
    
    // YES
    if ( [teacher respondsToSelector: @selector( alloc )] == YES ) {
        NSLog(@"teacher class responds to alloc method\n" );
    }


打印结果:


2012-07-04 14:39:49.853 ObjectiveCTest[2723:f803] teacher responds to setSize: method

2012-07-04 14:39:49.854 ObjectiveCTest[2723:f803] teacher class responds to alloc method

中间的那个判断我随便写了个selector,当然没有了。respondsToSelector 检查类方法 alloc返回YES





2.2 instancesRespondToSelector
// NO
    if ( [Person instancesRespondToSelector: @selector(teach)] == YES ) {
        NSLog(@"Person instance responds to teach method" );
    }
    
    // YES
    if ( [Teacher instancesRespondToSelector: @selector(teach)] == YES ) {
        NSLog(@"Teacher instance responds to teach method");
    }
    // YES
    if ( [Teacher instancesRespondToSelector: @selector(setName:)] == YES ) {
        NSLog(@"Teacher instance responds to setName: method" );
    }

打印结果:
2012-07-04 14:52:29.378 ObjectiveCTest[2961:f803] Teacher instance responds to teach method
2012-07-04 14:52:29.379 ObjectiveCTest[2961:f803] Teacher instance responds to setName: method





3、Objective-C的id类型

C++ 使用的是强类型:对象必须符合其类型,否则不能通过编译。在 Objective-C 中,id类型类似于(void*) ,可以指向任何类的实例。而不需要强制转换。

下面看看使用,

先把Teacher类中的 teach方法修改一下,改成


-(void)teach

{

    NSLog(@"%@ 教数学" ,name);

}

然后实现并调用
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    Person *person = [[Person alloc] init];
    Teacher *teacher = [[Teacher alloc] init];
    
    id p = person;
    id t = teacher;
    [t setName:@"张三老师"];
    [t teach];
    
    [person release];
    [teacher release];
    [pool release];


打印结果:
2012-07-04 14:57:55.905 ObjectiveCTest[3085:f803] 张三老师 教数学


分享到:
评论

相关推荐

    From C++ to Objective-C

    Objective-C的语法结构与C语言非常相似,但在面向对象方面有显著的不同之处。下面是一些基本的语法特性: ##### 2.1 关键字 Objective-C引入了一些新的关键字,如`@interface`, `@implementation`, `@end`, `@...

    Objective-C 入门指南基础与实践.docx

    - **对象类型:** 如 `NSString`、`NSArray` 等,这些是 Objective-C 中的重要组成部分,用于处理更复杂的数据结构。 ```objective-c int number = 10; NSString *string = @"Hello, Objective-C!"; ``` 2. **...

    Objective-C入门指南

    - **Id类型**: 表示任何Objective-C对象,用于不确定对象类型的情况。 - **动态类型识别(Dynamic Type Recognition)** - 类型判断(`isKindOfClass:`) - 类型转换(`[object isKindOfClass:]`) - **类别(Categories)...

    From C++ to Objective-C version 1.9

    Objective-C支持运行时类型检查,可以使用`isKindOfClass:`等方法来安全地执行下转型操作。 #### 七、继承 Objective-C支持单一继承和多重继承,但多重继承的使用相对较少。 ##### 7.1 单一继承 Objective-C中的...

    Objective-C简单继承代码

    Objective-C是一种强大的面向对象编程语言,特别是在iOS和macOS应用开发中广泛使用。在这个场景中,我们关注的是Objective-C中的“继承”概念,这在创建类的层次结构中扮演着核心角色。继承允许一个类(子类或派生类...

    Objective-C基础教程 第2版

    - 这是Objective-C的基础库,包含了基本的数据类型、集合类(如NSArray、NSDictionary)以及文件I/O等操作。 8. **Cocoa Touch与Cocoa**: - 对于iOS开发,Objective-C使用Cocoa Touch框架,提供了UI组件和触摸...

    探索NSObject的协议精髓:Objective-C中的基础方法解析

    2. **动态运行时**:具备动态类型和动态绑定的特点,允许在运行时查询对象的类型和调用方法。 3. **消息传递**:通过消息传递机制实现对象间通信。 4. **C 语言兼容**:与 C 语言高度兼容,几乎所有的 C 语言代码...

    Objective-C 软件编码规范(适用iPhone,iPad编程)

    Objective-C软件编码规范是针对iOS应用开发中的编程实践制定的一套规则,旨在提高代码的可读性、可维护性和团队协作效率。以下是对规范中关键点的详细解释: 1. **目的**: 编码规范的主要目的是确保代码的一致性...

    objc4-750-master.zip

    Objective-C runtime是Apple开发的一种运行时系统,它是Objective-C语言的核心组成部分,使得Objective-C具备了动态性与灵活性。在objc4-750-master.zip这个压缩包中,包含了Objective-C runtime的最新版本objc4-750...

    isKindOfClass和isMemberOfClass的底层区别

    BOOL res1 = [(id)[NSObject class]isKindOfClass:[NSObject class]];//1 BOOL res2 = [(id)[NSObject class]isMemberOfClass:[NSObject class]];//0 BOOL res3 = [(id)[LGPerson class]isKindOfClass:[LGPerson ...

    Object-C(中文版)

    - **动态识别(Dynamic types)**: Objective-C支持运行时类型检查,可以利用`isKindOfClass:`或`respondsToSelector:`等方法来确定对象的类型和是否能响应某个方法。 - **Categories**: 类别是Objective-C的一个...

    Object-C中文版

    - **动态性**:Objective-C是一种动态类型语言,对象可以在运行时确定其类型并响应消息。 - **开源**:Objective-C的编译器是基于GCC的,因此可以在多种平台上进行编译和运行。 #### 二、环境搭建 **Linux/FreeBSD...

    自定义tableview实现手势单元_Objective-C_下载.zip

    Objective-C是苹果官方推荐的编程语言之一,用于构建iOS应用。本教程将详细讲解如何使用Objective-C自定义UITableView,实现手势识别功能,以增强用户体验。 首先,我们要了解UITableView的基本结构。UITableView由...

    rust-objc:Rust的Objective-C运行时绑定和包装

    Rust的Objective-C运行时绑定和包装。 文档: : 板条箱: : 消息传递对象 可以使用msg_send! Objective-C对象发送消息msg_send! 巨集: let cls = class! (NSObject); let obj: * mut Object = msg_send! [cls,...

    Objective-C类方法中使用self注意事项

    在Objective-C编程中,类方法和实例方法是两种不同的调用方式,它们各自有特定的使用场景和规则。本文将详细探讨在类方法中使用`self`的关键注意事项,以帮助开发者更好地理解和避免潜在的问题。 首先,理解...

    ios中文开发

    Objective-C结合了C语言的基础语法与Smalltalk的面向对象特性,使得开发者能够更加高效地构建复杂的软件系统。本文将详细介绍Objective-C中的基本数据类型及其特点,并通过具体示例帮助读者更好地理解和掌握这些概念...

    IOS面试题--(某大型移动互联网公司)

    这些题目涵盖了iOS开发中的多个核心知识点,包括动态语言特性、内存管理、Objective-C语法、多线程、协议、文件编译、内存管理、Objective-C对象生命周期、字符串比较、对象序列化、视图坐标系统以及线程管理等。...

    objecitve-c 2.0 教程

    3. **动态类型**:Objective-C 支持运行时类型识别,可以通过 `isKindOfClass:` 或 `respondsToSelector:` 方法检查对象的实际类型及其支持的方法。 #### 五、标准库与框架 Objective-C 2.0 提供了丰富的标准库和...

Global site tag (gtag.js) - Google Analytics