'[Objective-C]프로퍼티'에 해당되는 글 1건

  1. 2010.06.22 [Objective-C]프로퍼티
오브젝트C2010. 6. 22. 09:54
[Objective-C]프로퍼티
Objective-C 2.0에서 declared property 와 dot operator 가 새로 도입 되었다.
이것을 사용함에 따라 객체가 가지는 속성값을 조작한다는 느낌으로 프로그램을 개발 할 수 있다.
declared property에 관한 기능을 요약하면 다음과 같다.

* 접근자 메소드의 생성
인스턴스 변수를 지정해서 전형적인 접근자 메소드를 생성하는 것이 가능하다. getter/setter모두를 만들거나 하나만 만들것인지는 지정 가능하다. 대응하는 접근자를 개발자가 직접 정의도 가능.

* 접근자의 호출을 간단히 기술
접근자 메소드를 dot operator '.'를 사용해서 호출하는 것이 가능하다. setter의 호출은 구조체의 멤버로의 대입, getter는 멤버의 값을 참조하는 기법으로 기술된다. 이 기법은 declared property 에 국한되지 않고 접근자 메소드가 정의되어 있으면 사용이 가능하다.

* property 관련 introspection
클래스에 어떤 declared property 가 있고 그 이름과 타입이 무엇인가에 대한 정보를 런타임에 동적으로 확인하는것이 가능.

Objective-C 1.0은 정보의 은닉성을 중시하여 변수를 외부에 공개하지 않고 참조나 변경은 모두 메소드 호출을 통하는 방법을 적용했었다. 하지만 UML을 시작으로 객체의 속성과 메소드를 구분해서 생각하는 프로그래밍 기법이 일반화 되어 새롭게 도입된 도트 연산자를 사용한 접근자 호출은 구조체 멤버를 조작하는 것과 같은 느낌으로 속성값을 취급할 수 있다. 그리고 변수를 직접 조작하는 것은 아니기 때문에 정보의 은닉성도 유지할수 있다.


- introspection
데이터 형식이나 내용을 설명하기 위한 데이터를 메타 데이터라고 부르며 정보를 설명하기 위한 정보를 메타 정보라고 한다. 어떤 클래스가 어떤 메소드나 프로퍼티를 가지는가라는 정보도 일종의 메타 정보가 된다. 객체지향 언어에서는 이런 메타 정보를 프로그램에서 동적으로 접근하는 기능을 인트로스펙션 혹은 리플렉션이라고 부른다. Objective-C의 responderToSelector 메소드도 인트로스펙션의 한 종류이다.

기존 방식(접근자)에 의한 처리
Creture1.h
#import <Foundation/Foundation.h>

@interface Creture1 : NSObject {
    NSString *name;
    int hitPoint;
    int magicPoint;
}

-(id)initWithName:(NSString *)str;
-(NSString *)name;
-(int)hitPoint;
-(void)setHitPoint:(int)val;
-(int)level;

@end

Creture1.m
#import "Creture1.h"

@implementation Creture1

-(id)initWithName:(NSString *)str{
    if((self = [super init]) != nil){
        name = str;
        hitPoint = magicPoint = 10;
    }
    return self;
}

-(NSString *)name{
    return name;
}

-(int)hitPoint{
    return hitPoint;
}

-(void)setHitPoint:(int)val{
    hitPoint = val;
}

-(void)level{
    return (hitPoint + magicPoint) / 10;
}
@end

프로퍼티에 의한 구현
Creture2.h
#import <Foundation/Foundation.h>

@interface Creture2 : NSObject {
    NSString *name;
    int hitPoint;
    int magicPoint;
}

-(id)initWithName:(NSString *)str;
@property(readonly) NSString *name;
@property int hitPoint, magicPoint;
@property(readonly)int level;

@end

Creture2.m
#import "Creture2.h"

@implementation Creture2

-(id)initWithName:(NSString *)str{
    if((self = [super init]) != nil){
        name = str;
        hitPoint = magicPoint = 10;
    }
    return self;
}

@synthesize name;
@synthesize hitPoint, magicPoint;
@dynamic level;

-(int)level{
    return (hitPoint + magicPoint) / 10;
}

@end

main.m
#import "Creture2.h"

int main(void){
    Creture2 *a = [[Creture2 alloc] initWithName:@"Nike"];
    a.hitPoint = 50;
    printf("%s : HP = %d (LV=%d)\n", [a.name UTF8String], a.hitPoint, a.level);
    return 0;
}





@property는  컴파일러 지시자 이다. @property는 선언을 하기만 하므로 인스턴스 변수로 구현되어 있는지에 대해서는 상관하지 않는다.
읽기 전용 프로퍼티를 선언하기 위해서는 @property 뒤에 (readonly)라는 옵션을 지정한다.
@synthesize 는 컴파일러 지시자로 게터와 세터를 인터페이스에서 선언한 속성에 맞춰 구성된다.
보통 메소드는 인터페이스에 선언이 없어도 정의만 구현부에 기술할 수 있지만 디클레어드 프로퍼티의 경우 인터페이스에서 @property 선언이 없으면 @synthesize를 기술할 수 없다.
level의 경우는 독자적인 메소드를 정의하고 있으므로 @synthesize를 사용하지 않고 @dynamic이라는 컴파일러 지시자를 사용하였다. 하지만 이는 필수는 아니다.



출처 : http://blog.naver.com/PostView.nhn?blogId=khagaa&logNo=30084787263

'오브젝트C' 카테고리의 다른 글

[Objective-C]메세지 포워딩  (0) 2010.06.22
[Objective-C]존  (0) 2010.06.22
[Objective-C]프로퍼티  (0) 2010.06.22
[Objective-C]클래스 클러스터  (0) 2010.06.22
[Objective-C]가비지 컬렉션  (0) 2010.06.22
[Objective-C]카테고리 예제  (0) 2010.06.22
Posted by 오늘마감

댓글을 달아 주세요