@property
@interface Example : NSObject
{
float value;
}
- (float)value;
- (void)setValue:(float)newValue;
위와같이 프로퍼티에 대한 getter와 setter 메서드를 선언해 줄 수 있습니다. 하지만 이 접근자 메서드를 만들어주는 것은 항상 같은 형태로 반복되는 지루한 작업이기 때문에 Objective-C 2.0에서부터는 @property 지시어를 사용해서 getter와 setter에 대한 코드를 자동으로 생성할 수 있도록 해줍니다.
@interface Example : NSObject
{
float value;
}
@property float value;
정확한 문법은 @property(attributes [, attribute2, ...]) type name;의 형태이고 앞의 코드에서 6,7라인의 코드대신에 위처럼 @property 지시어를 사용하면 자동으로 앞의 코드로 변환해 줍니다. 위에서 보는 것처럼 getter의 이름은 "프로퍼티이름"이 되고 setter의 이름은 "set프로퍼티이름"이 됩니다. 만약 getter의 이름을 바꾸려면 @property(getter=getValue) float value;와 같이 써주면 getter를 getValue 함수를 써서 사용할 수 있습니다. 프로퍼티를 IB아웃렛으로 지정하려면 @property (nonatomic, retain) IBOutlet NSButton *myButton;와 같이 IBOutlet 식별자를 사용할 수 있습니다.
(attributes [, attribute2, ...])부분에서 사용이 가능한 속성들은 아래와 같습니다.
- getter=getterName - getter의 이름을 getterName로 지정합니다.
- setter=setterName - setter의 이름을 setterName로 지정합니다.
- readwrite - 기본동작으로 getter와 setter를 모두 만듭니다. Mutually exclusive로 readwrite합니다.
- readonly - getter만 만듭니다. Mutually exclusive로 readwrite합니다. 값을 할당하려고 하면 컴파일 오류가 발생합니다.
- assign - 기본동작이며 setter가 간단한 할당을 사용합니다.(예 location = where;) 객체를 소유할 필요가 없을때 사용합니다.
- retain - assign과 비슷하지만 레퍼런스 카운트를 증가시킵니다. Mutually exclusive로 assign과 copy합니다. 포인터객체를 할당할 경우에는 외부에서 객체가 릴리즈되어 파괴된 객체를 참조하는 문제를 막기 위해서 클래스가 멤버객체를 소유하도록 레퍼런스카운트를 증가시킵니다.(이전 값을 release 합니다.)
- copy - 할당하는데 객체의 복사본을 사용합니다. Mutually exclusive로 assign과 retain합니다. 포인터객체의 경우 레퍼런스의 값이 바뀌어 프로퍼티의 값이 바뀌는 걸 막기 위해 setter에서 복사본을 만들어서 할당하며 copy를 사용하려면 NSCopying 프로토콜을 구현한 객체에서만 유효합니다.
- nonatomic - 엑세서들을 non-atomic으로 지정합니다. 멀티프로세서 환경해서는 지정해줘야 합니다. 이는 Mutually exclusive락으로 접근자 메서드를 보호하지 말라고 지시하는 것입니다. atomic이 기본동작입니다.
@synthesize
@property를 사용해서 프로퍼티들에 대한 getter와 setter를 선언했으면 @implementation에서 실제 코드를 추가해 주어야 합니다. @property를 사용한 것은 단지 컴파일러가 @implementation에서 getter와 setter메서드가 작성되었다는 것을 기대하도록 하는 것입니다.
@implementation Example
-(float) value
{
return value;
}
-(void) setValue: (float) newValue
{
value = newValue;
}
@end
위와 같이 실제 구현코드를 작성해주어야 합니다. 이는 아래코드처럼 @synthesize 지시어를 사용하면 다음과 같이 작성해 줄 수 있습니다.
@implementation Example
@synthesize value;
@end
@dynamic
@dynamic 지시어는 @synthesize대신에 사용할 수 있으며 getter와 setter메서드가 클래스 자신에 의해서 구현되지 않고 (슈퍼클래스같은)다른 어딘가에 구현되어 있다고 알려주어 getter/setter가 구현되어 있지 않아도 컴파일러 경고를 받지 않도록 해줍니다.
Super class :
@property (nonatomic, retain) NSButton *someButton;
@synthesize someButton;
Sub class :
@property (nonatomic, retain) IBOutlet NSButton *someButton;
@dynamic someButton;
위와 같이 작성함으로써 someButton에 대한 구현책임이 델리게이트 되었음을 의미합니다. 혹은 CoreData의 NSManagedObject 클래스처럼 접근자 메서드들이 컴파일타임이 아닌 런타임시의 제공되는 경우에도 컴파일타임에 오류가 나지 않도록 하기 위해서 @dynamic 지시어를 사용할 수 있습니다.
Comments