atomic 프로퍼티의 접근자 메서드

많은 iOS책들에서 프로퍼티는 대부분 nonatomic 속성으로 지정한다. 이 때 nonatomic은 항상 명시하는데, 이는 Objective-C에서 프로퍼티의 디폴트는 atomic이기 때문이다. 그런데 이게 정말, nonatomic이어야 하기 때문에 이렇게 하는 것인지, 맞는 것인지는 좀 아리송한데…

atomic은 예전에도 한 번 설명한 적이 있는데, 접근자를 호출한 스레드에서 그 프로퍼티를 읽거나 쓰는 중간에는 다른 스레드나 큐에서 액세스 하지 못하도록 한다는 의미이다. 따라서 멀티 스레드나 백그라운드 작업을 염두에 둔다면 atomic 속성에 대해서도 고려를 해야 한다는 의미이다.

어떤 스레드에서 객체의 프로퍼티에 접근할 때 다른 스레드에서의 접근을 막는 것을 공교롭게도 “동기화”라고 표현하더라. 정말 와닿지 않는 표현이다. 서로 다른 스레드에서 접근할 때 같은 값을 돌려주는 것을 보장하는 것도 아닌데 말이다. 어쨌든, atomic으로 설정한 프로퍼티의 setter나 getter는 다음과 같은 모양이 될 것으로 추측된다.

-(NSNumber*)myIntegerValue
{
    @synchronized(self) {
        return _myIntegerValue;
    }
}
-(void)setMyIntegerValue:(NSInteger*)newIntegerValue;
{
    @synchronized(self) {
        _myIntegerValue = newIntegerValue;
    }
}

저렇게 synchronized(self) 라고 하면 저 블럭 사이의 코드가 실행될 때는 self 전체가 이 접근자를 호출한 스레드에 대해 atomic해진다. 다른 스레드에서 접근할 때에, 이 스레드는 요 블럭 사이의 코드가 모두 실행을 완료할 때 까지 기다리게 된다.

일반적으로 atomic하게 선언된 프로퍼티에 대해 접근자 메소드를 커스터마이징하려고 하면 오류가 난다. 그래서 왠만하면 nonatomic으로 사용하는게 역시나 정신 건강에 좋을 것 같다. 물론 atomic한 접근이 필요한 케이스도 분명 있지만, 내가 저런 경우를 만날만한 앱을 만들일은 없을 것 같다.