Tag Archives: readonly

[iPhone] Object-C : Declared Properties

이번에는 Object-C의 Property에 대해서 이야기를 해볼까 합니다.

어떻게 보면 조금 필요없어 보일수도 있고 어찌보면 MVC(Model, View, Controller)개발 기법과도 밀접한 연관이 있어 보입니다.

하지만 일반적으로 MVC개발에서도 setter/getter로 구성 된 도메인 객체를 따로 두고 있듯이 Object-C에서도 역시 비슷한 구현을 할 수 있는것 같습니다.

Object-C에서 일반적으로 객체의 Property에 접근하기 위해서는 한쌍의 접근자 메서드(getter/setter)를 사용합니다.

이 메서드들을 사용함으로써 객체지향 프로그래밍의 캡슐화(Encapsulation)에 더욱 충실 할 수 있습니다.

관련된 자료는 Object-Oriented Programming with Objective-CMechanism Of Abstraction을 찾아보라고 하는군요.

Property를 정의함으로써 효과적으로 접근자 메서드들을 간략화 시키는 효과를 가져올 수 있습니다.

Property를 사용하기 위해서 일반적으로 @property 지시자와 @synthesize 지시자를 함께 사용합니다.

@property 지시자는 클래스의 @interface 내부에 선언하며 다음과 같은 형식으로 선언합니다.
[code]@property(attributes) type name;[/code]
하나의 Property 선언은 두개의 접근자 메서드와 동일한 기능을 갖습니다.
[code]@proprty float value;[/code]
위의 선언은 다음과 같이 두가지 메서드를 선언한것과 같은 기능을 하게 됩니다.
[code]- (float)value;
– (void)setValue:(float)newValue;[/code]

@property 지시자의 attributes 에는 다음과 같은 정의를 할 수 있습니다.

getter=gettername
기본적으로 Property의 getter 메서드 명은 Property 자신의 이름과 동일 (예 : Property가 foo일 경우 foo)
하지만 이 기본 설정을 내가 원하는 메서드명으로 변경 할 수 있습니다.

setter=settername
Property의 setter 메서드 명은 setPropertyName: 입니다. (예 : Property가 foo일 경우 setFoo:)
역시나 이 기본 설정을 내가 원하는 메서드명으로 변경 할 수 있습니다.

readwrite (DEFAULT)
Property의 값을 읽고 쓸 수 있다는 것입니다. 이 설정은 기본 설정입니다.

readonly
Property의 값을 단지 읽기만 할수 있다고 정의하는 속성입니다.
이 속성은 @implementation 블럭 안에서 오로지  getter 메서드만 필요할 경우에 사용합니다.
@synthesize 지시자를 사용하였을 경우에는 역시나 getter 메서드의 역할만을 하게 됩니다.
값을 대입 하려고 할 경우 에러를 출력하게 됩니다.

assign (DEFAULT)
단순하게 값을 대입합니다. 기본설정입니다. 이전에 어떤 객체를 가리키고 있던 Property라면 이로 인해 해당 객체는 미아가 되어 메모리릭의 주범이 될 수 있습니다. 가비지콜렉터를 사용하지 않는다면 사용을 피해야 합니다.

retain
이것은 assign과 비슷하지만 조금 다릅니다. 이전에 가리키고 있던 객체가 있다면 해당 객체를 Release하여 메모리에서 제거 합니다. 가비지콜렉터를 사용한다면 결과적으로 assign과 동일한 결과를 가지겠지만 좀더 명시적으로 사용해 주면 좋을것 같습니다.

copy
객체를 바로 대입하지 않고 해당 객체의 복사 메서드를 Invoke호출합니다.
그리하여 다른 메모리 영역에 복사본을 만든 다음 그것을 반환하게 됩니다. 이전에 가리키고 있던 값은 Release 시킵니다.

nonatomic
이 속성은 접근자 메서드가 Atomic 하지 않게 동작하게 합니다(?). 기본적으로 접근자는 Atomic하게 동작합니다.
Atomic이라는 말은 멀티스레드 등으로 구성된 프로그램이 특정 접근자 메서드를 호출할때 서로 충돌이 나지 않도록(보통 세마포어니 크리티컬섹션이니 하는 말들 들어보셨을겁니다.) 객체 레벨에서 Lock을 걸고 Property에 접근하게 되는데요 매우 좋은 이야기지만 접근할때 마다 Lock을 걸고 다시 푸는 작업이 반복되므로 퍼포먼스를 떨어뜨리는 결과를 가져오게 됩니다.
이런 접근이 필요없다면 이 속성을 사용하여 Non-Atomic하게 동작하도록 만들어 주시는 것이 좋습니다.

이제 Property에 대해 거의 모든것을 알게 된것 같네요. 이제 예제를 한번 볼까요?
[code]@interface MyClass : NSObject {
    NSString *value;
}
@property(copy, readwrite) NSString *value;
@end

@implementation MyClass
@synthesize value;
@end[/code]
value라는 이름의 Property의 getter 메서드 명은 value이고 setter 명은 setValue입니다.

값을 대입할때 복사가 일어나고 읽고 쓰기를 할 수 있습니다. 또한 nonatomic 속성이 없으니 atomic하게 동작하겠군요.

마지막으로 Property를 사용할때 주의사항이 한가지 있습니다.

객체가 제거 될때 소멸자로 dealloc이 호출되는데 Property들이 자동으로 소거되지 않아 명시적으로 제거해 주셔야 합니다.
[code]- (void)dealloc {
    [value release];
    [super dealloc];
}[/code]