IOS反射机制的几个重要函数

/*
object-c的语法学习
main.mm
made by davidsu33

-(BOOL)isKindOfClass:            classObj
                     是否是其子孙或一员

-(BOOL)isMemberOfClass:            classObj
         是否是其一员

-(BOOL)respondsToSelector:            selector
         是否有这种方法

+(BOOL)instancesRespondToSelector:            selector
         类的对象是否有这种方法

-(id)performSelector:            selector
         执行对象的方法
*/

#import <Foundation/Foundation.h>

typedef struct
{
    float x,y,w,h;
}Rect;

typedef struct
{
    float x,y;
}Point;

@protocol DSShape

@optional
- (int) getArea;

@optional
- (Rect) getBoundingRect;

@optional
- (NSMutableArray*) getPointArray;

@end

@interface DSRectangle : NSObject<DSShape>
{
    Rect _rect;
    NSString* _name;
}

@property (readwrite, nonatomic)
Rect rect;

@property(readwrite, nonatomic)
NSString *name;

- (id) init;
- (void) dealloc;
- (NSString*) className;
- (BOOL) isSqure;
- (void) showInfo;
- (Rect) getBoundingRect;
@end

@implementation DSRectangle
@synthesize rect = _rect, name = _name;

- (id) init
{
    if(self = [super init])
    {
        self.rect = Rect{0,0,0,0};
        self.name = nil;
        NSLog(@"%@ initialize", [self className]);
    }

    return self;
}

- (void) dealloc
{
    NSLog(@"%@ dealloc", [self className]);
}

- (NSString*) className
{
    return NSStringFromClass([self class]);
}

- (BOOL) isSqure
{
    return self.rect.w == self.rect.h;
}

- (void) showInfo
{
    id s = [[NSString alloc] initWithFormat:@"x=%f,y=%f,w=%f,h=%f, name=%@",_rect.x,
                                        _rect.y,_rect.w,_rect.h,self.name];
    NSLog(@"DSRectangle: %@",s);
}

- (Rect) getBoundingRect
{
    return self.rect;
}
@end

@interface DSSqure : DSRectangle
- (id) init;
- (void) dealloc;
- (float) sideLength;
@end

@implementation DSSqure
- (id) init
{
    if(self = [super init])
    {
        NSLog(@"%@ initialize", [self className]);
    }

    return self;
}

- (void) dealloc
{
    NSLog(@"%@ dealloc",[self className]);
}

- (float) sideLength
{
    return self.rect.w;
}
@end

#define SyntaxTest(x)    do{        NSLog(@"%@ = %@", [[NSString alloc] initWithCString:#x], x?@"TRUE":@"FALSE");    }while(0)

void dynamic_attr_test()
{
    DSRectangle *re = [[DSRectangle alloc] init];
    re.name = @"Rectangle";
    re.rect = Rect{10,20,200,300};

    DSSqure *sq = [[DSSqure alloc] init];
    sq.name = NSStringFromClass([sq class]);
    sq.rect = Rect{30,40,500,600};

    //NSLog(@"rectangle name:%@", re.name);
    [re showInfo];
    [sq showInfo];

    NSLog(@"\n-------------------isKindOfClass-----------------");
    SyntaxTest([re isKindOfClass: [NSObject class]]);
    SyntaxTest([re isKindOfClass: [DSRectangle class]]);
    SyntaxTest([DSRectangle isKindOfClass: [NSObject class]]);
    SyntaxTest([DSRectangle isKindOfClass: [DSRectangle class]]);

    //动态语法测试
    //isKindOfClass 对象是否是该类,或者该类祖先的实例
    SyntaxTest([re isKindOfClass: [NSObject class]]);
    SyntaxTest([re isKindOfClass: [DSRectangle class]]);

    //isMemberOf 对象是否是某一个类的实例
    NSLog(@"\n-------------------isMemberOfClass-----------------");
    SyntaxTest([re isMemberOfClass: [NSObject class]]);
    SyntaxTest([re isMemberOfClass: [DSRectangle class]]);

    SyntaxTest([DSRectangle isMemberOfClass: [NSObject class]]);
    SyntaxTest([DSRectangle isMemberOfClass: [DSRectangle class]]);

    //如果实例是输入参数,则selector是类的成员函数返回TRUE
    //如果类名称是输入参数,则selector是类的静态函数返回TRUE,否则返回FALSE
    NSLog(@"\n-------------------respondsToSelector-----------------");
    SyntaxTest([re respondsToSelector: @selector(init)]);
    SyntaxTest([re respondsToSelector: @selector(NoThat)]);
    SyntaxTest([re respondsToSelector: @selector(showInfo)]);

    SyntaxTest([DSRectangle respondsToSelector: @selector(init)]);
    SyntaxTest([DSRectangle respondsToSelector: @selector(NoThat)]);
    SyntaxTest([DSRectangle respondsToSelector: @selector(showInfo)]);

    //查看协议接口
    SyntaxTest([re respondsToSelector: @selector(getArea)]);
    SyntaxTest([re respondsToSelector: @selector(getBoundingRect)]);

    SyntaxTest([DSRectangle respondsToSelector: @selector(getArea)]);
    SyntaxTest([DSRectangle respondsToSelector: @selector(getBoundingRect)]);

    //判断该方法是实例接口(类成员函数)还是类函数(静态函数)
    NSLog(@"\n-------------------instancesRespondToSelector-----------------");
    /*SyntaxTest([re instancesRespondToSelector: @selector(init)]);
    SyntaxTest([re instancesRespondToSelector: @selector(NoThat)]);
    SyntaxTest([re instancesRespondToSelector: @selector(showInfo)]);
    */

    //instancesRespondToSelector只能输入类,不能写其他的
    SyntaxTest([DSRectangle instancesRespondToSelector: @selector(init)]);
    SyntaxTest([DSRectangle instancesRespondToSelector: @selector(NoThat)]);
    SyntaxTest([DSRectangle instancesRespondToSelector: @selector(showInfo)]);

    /*
    1. respondsToSelector既可以检查类(是否响应指定类方法),也可以检查实例(是否响应指定实例方法)
    2. instancesRespondToSelector只能写在类名后面,但检测的是实例(是否响应指定实例方法)
    可以认为[Test instancesRespondToSelector:sel]等价于[obj respondsToSelector:sel]
    */

    //[re release];
    //[sq release];
}

int main()
{
    id arp = [[NSAutoreleasePool alloc] init];
    dynamic_attr_test();
    getchar();
    [arp drain];

    return 0;
}

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。