[Objective C] 07 DynamicTypes

프로그래밍/iPhone Dev 2009. 10. 30. 16:49 Posted by galad
DynamicTypes

Rectangle.h
#import <Foundation/NSObject.h>

@interface Rectangle2: NSObject {
    int width;
    int height;
}

-(Rectangle2*) initWithWidth: (int) w height: (int) h;
-(id) initWithWidth2: (int) w height: (int) h;
-(void) setWidth: (int) w;
-(void) setHeight: (int) h;
-(void) setWidth: (int) w height: (int) h;
-(int) width;
-(int) height;
-(void) print;
@end


Rectangle.m
#import "Rectangle.h"
#import <stdio.h>

@implementation Rectangle2
-(Rectangle2*) initWithWidth: (int) w height: (int) h {
    self = [super init];
   
    if(self) {
        [self setWidth: w height: h];
    }
   
    return self;
}

-(id) initWithWidth2: (int) w height: (int) h {
    self = [super init];
   
    if(self) {
        [self setWidth: w height: h];
    }
   
    return self;
}

-(void) setWidth: (int) w {
    width = w;
}

-(void) setHeight: (int) h {
    height = h;
}

-(void) setWidth: (int) w height:(int) h {
    width = w;
    height = h;
}

-(int) width {
    return width;
}

-(int) height {
    return height;
}

-(void) print {
    printf("width = %i, height = %i", width, height);
}
@end


Square.h
#import "Rectangle.h"

@interface Square: Rectangle2
-(Square*) initWithSize: (int) s;
-(void) setSize: (int) s;
-(int) size;
+(void) setSize; // respondsToSelector 테스트용
@end


Square.m
#import "Square.h"

@implementation Square
-(Square*) initWithSize: (int) s {
    self = [super init];
   
    if(self) {
        [self setSize: s];
    }
   
    return self;
}

-(void) setSize: (int) s {
    width = s;
    height = s;
}

-(int) size {
    return width;
}

-(void) setWidth: (int) w {
    [self setSize: w];
}

-(void) setHeight: (int) h {
    [self setSize: h];
}

+(void) setSize {
}
@end


main.m
#import "Square.h"
#import "Rectangle.h"
#import <stdio.h>

int main(int argc, const char* argv[]) {
    Rectangle2* rec = [[Rectangle2 alloc] initWithWidth: 10 height: 20];
    Square* sq = [[Square alloc] initWithSize: 15];
   
    // is Member of class
    printf("\nis Member of class\n");
    // 1: sq instance가 Square 클래스의 멤버인가 - true
    if([sq isMemberOfClass: [Square class]] == YES) {
        printf("Square is member of Square class\n");
    }
    else {
        printf("Square is NOT member of Square class\n");
    }

    // 2: sq instance가 Rectangle2 클래스의 멤버인가 - flase
    if([sq isMemberOfClass: [Rectangle2 class]] == YES) {
        printf("Square is member of Rectangle2 class\n");
    }
    else {
        printf("Square is NOT member of Rectangle2 class\n");
    }

    // 3: sq instance가 NSObject 클래스의 멤버인가? - flase
    if([sq isMemberOfClass: [NSObject class]] == YES) {
        printf("Square is member of NSObject class\n");
    }
    else {
        printf("Square is NOT member of NSObject class\n");
    }
   
    // 4: Square 클래스가 NSObject 클래스의 멤버인가? - flase
    if([Square isMemberOfClass: [NSObject class]] == YES) {
        printf("Square class is member of NSObject class\n");
    }
    else {
        printf("Square class is NOT member of NSObject class\n");
    }
   
    // isMemberOfClass는 대상 class/instance가 비교 클래스일 때만 true.
    // supre class는 모두 무시.
   
    // is Kind of class
    printf("\nis Kind of class\n");
    // 5: sq instance가 Square 클래스의 종류인가? - true
    if([sq isKindOfClass: [Square class]] == YES) {
        printf("Square is kind of Square class\n");
    }
    else {
        printf("Square is NOT kind of Square class\n");
    }

    // 6: sq instance가 Rectangle2 클래스의 종류인가? - true
    if([sq isKindOfClass: [Rectangle2 class]] == YES) {
        printf("Square is kind of Rectangle2 class\n");
    }
    else {
        printf("Square is NOT kind of Rectangle2 class\n");
    }

    // 7: sq instance가 NSObject 클래스의 종류인가? - true
    if([sq isKindOfClass: [NSObject class]] == YES) {
        printf("Square is kind of NSObject class\n");
    }
    else {
        printf("Square is NOT kind of NSObject class\n");
    }
   
    // 8: Square 클래스가 NSObject 클래스의 종류인가? - true
    if([Square isKindOfClass: [NSObject class]] == YES) {
        printf("Square class is kind of NSObject class\n");
    }
    else {
        printf("Square class is NOT kind of NSObject class\n");
    }
   
    // isKindOfClass는 대상 class/instance가 비교 클래스이거나
    // 비교 클래스의 child class일 때만 true.
   
    // respondsToSelector
    printf("\nrespondsToSelector\n");
    // 9: sq instance는 selector(setSize:)에 응답하는가? - true
    if([sq respondsToSelector: @selector(setSize:)] == YES) {
        printf("Square responds to setSize: method\n");
    }
    else {
        printf("Square DOESN'T respond to setSize: method\n");
    }
   
    // 10: sq instance는 selector(setSize)에 응답하는가? - false
    if([sq respondsToSelector: @selector(setSize)] == YES) {
        printf("Square responds to setSize method\n");
    }
    else {
        printf("Square DOESN'T respond to setSize method\n");
    }
   
    // setSize: 와 setSize 의 차이점은? -> parameter를 받는 method와 그렇지 않은 method
    // parameter 없는 setSize method를 만들었을 경우엔 @selector(setSize)에도 응답한다.

    // 11: Square class는 selector(setSize:)에 응답하는가? - false
    if([Square respondsToSelector: @selector(setSize:)] == YES) {
        printf("Square class responds to setSize: method\n");
    }
    else {
        printf("Square class DOESN'T respond to setSize: method\n");
    }
       
    // 12: Square class는 selector(setSize)에 응답하는가? - true
    if([Square respondsToSelector: @selector(setSize)] == YES) {
        printf("Square class responds to setSize method\n");
    }
    else {
        printf("Square class DOESN'T respond to setSize method\n");
    }
   
    // instance method(-붙은 method)는 instance에만 응답하고
    // class method(+붙은 method)는 class에만 응답한다.
   
    // 13: sq instance는 selector(nonExistant)에 응답하는가? - false
    if([sq respondsToSelector: @selector(nonExistant)] == YES) {
        printf("Square responds to nonExistant method\n");
    }
    else {
        printf("Square DOESN'T respond to nonExistant method\n");
    }
   
    // 14: Square class는 selector(alloc)에 응답하는가? - true
    if([Square respondsToSelector: @selector(alloc)] == YES) {
        printf("Square class responds to alloc method\n");
    }
    else {
        printf("Square class DOESN'T respond to alloc method\n");
    }
   
    // 15: sq instance는 selector(alloc)에 응답하는가? - false
    if([sq respondsToSelector: @selector(alloc)] == YES) {
        printf("Square responds to alloc method\n");
    }
    else {
        printf("Square DOESN'T respond to alloc method\n");
    }
   
    // instancesRespondToSelector
    // 말 그대로 클래스의 instance가 selector에 응답하는가를 체크하는 method
    printf("\ninstancesRespondToSelector\n");
    // 16: Rectangle2의 instances는 selector(setSize:)에 응답하는가? - false
    if([Rectangle2 instancesRespondToSelector: @selector(setSize:)] == YES) {
        printf("Rectangle2 instances respond to setSize: method\n");
    }
    else {
        printf("Rectangle2 instances DON'T respond to setSize: method\n");
    }
   
    // 17: Square의 instances는 selector(setSize:)에 응답하는가? - true
    if([Square instancesRespondToSelector: @selector(setSize:)] == YES) {
        printf("Square instances respond to setSize: method\n");
    }
    else {
        printf("Square instances DON'T respond to setSize: method\n");
    }
   
    // 18: Square의 instances는 selector(setSize)에 응답하는가? - false
    if([Square instancesRespondToSelector: @selector(setSize)] == YES) {
        printf("Square instances respond to setSize method\n");
    }
    else {
        printf("Square instances DON'T respond to setSize method\n");
    }

    [rec release];   
    [sq release];

    system("PAUSE");
    return 0;
}


결과
is Member of class
Square is member of Square class
Square is NOT member of Rectangle2 class
Square is NOT member of NSObject class
Square class is NOT member of NSObject class

is Kind of class
Square is kind of Square class
Square is kind of Rectangle2 class
Square is kind of NSObject class
Square class is kind of NSObject class

respondsToSelector
Square responds to setSize: method
Square DOESN'T respond to setSize method
Square class DOESN'T respond to setSize: method
Square class responds to setSize method
Square DOESN'T respond to nonExistant method
Square class responds to alloc method
Square DOESN'T respond to alloc method

instancesRespondToSelector
Rectangle2 instances DON'T respond to setSize: method
Square instances respond to setSize: method
Square instances DON'T respond to setSize method
계속하려면 아무 키나 누르십시오 . . .

* Dev-C에 확실히 버그가 있음. 기존 .h, .m 파일 자체를 복사해서 프로젝트에 추가하면 인식이 안됨. 컴파일 시 클래스를 못찾음...
 꼭 프로젝트->New File로 추가해줘야 링크가 걸림.

- There are several methods for working with dynamic types in Objective-C
      -(BOOL) isKindOfClass: classObj is object a descendent or member of classObj
      -(BOOL) isMemberOfClass: classObj is object a member of classObj
      -(BOOL) respondsToSelector: selector does the object have a method named specifiec by the selector
      +(BOOL) instancesRespondToSelector: selector does an object created by this class have the ability to respond to the specified selector
      -(id) performSelector: selector invoke the specified selector on the object
- isMemberOfClass는 대상 class/instance가 비교 클래스일 때만 true. supre class는 모두 무시.
- isKindOfClass는 대상 class/instance가 비교 클래스이거나 비교 클래스의 child class일 때만 true.
- setSize: 와 setSize 의 차이점은? -> parameter를 받는 method와 그렇지 않은 method
- instance method(-붙은 method)는 instance에만 응답하고 class method(+붙은 method)는 class에만 응답한다.
- instancesRespondToSelector는 말 그대로 클래스의 instance가 selector에 응답하는가를 체크하는 method. 타겟은 당연히 class.

'프로그래밍 > iPhone Dev' 카테고리의 다른 글

[Objective C] 09 Posing  (0) 2009.11.10
[Objective C] 08 Categories  (0) 2009.11.09
[Objective C] 06 Inheritance  (1) 2009.10.30
[Objective C] 05 The Id Type  (1) 2009.10.29
[Objective C] 04 Exceptions  (0) 2009.10.28