본문 바로가기

iOS/Objective-C

Objective-C) 프로퍼티 (2/2) - 속성(Attribute)

 

 

안녕하세요 :) 소들입니다!!

이번 포스팅에선 프로퍼티의 속성에 대해 공부하려고 해요

음.. 속성이 뭐냐고 묻는다면 프로퍼티를 생성할 때 생략해도 되지만,

 

 

 

 

이런 식으 () 안에 프로퍼티의 속성을 지정할 수 있어요!

오늘은 프로퍼티엔 어떤 속성들이 있고,

어떤 것들을 지정할 수 있는지 봐볼 거예요 :)

 

모든 포스팅은 편의 말투로 합니다~!!

 

 

 

1. getter / setter

 

이 속성은 다음과 같이 사용하는데,

 

 

@property (getter=customGetName, setter=customSetName:) NSString *name;
 

 

 

이는 프로퍼티의 getter, setter의 이름을

직접 지정해주고 싶을 때 위와같이 사용함!!!!!

그럼 

 

 

내가 지정해준 이름으로, getter / setter의 이름이 바뀜!

 

 

 

 

2. readwrite / readonly

 

먼저 사용법과 의미는 이름 그대로

 

 

@property (readwrite) NSString *name;
 

 

 

readwrite = getter / setter 둘다 만듦

 

 

@property (readonly) NSString *name;
 

 

 

readonly = getter 하나만 만듦

 

요런 뜻임!!! 


아무 것도 지정하지 앟으면 readwrite로 getter / setter 두 개가 모두 생성되지만,
readonly로 할 경우

 

 

 


프로퍼티의 setter가 생성되지 않음 :)

 

 

 

 

3. atomic / nonatomic

 

이것은 서로 반대의 개념인데,

먼저 아무 것도 설정하지 않을 경우, 

default 값이 atomic임!!

 

 

@property (atomic) NSString *name;
 



atomic / nonatomic의 차이점이 무엇이냐면,

멀티 쓰레드 환경에서, 동시에 이 프로퍼티에 접근하려 할 때,

자동으로 이 프로퍼티의 getter / setter에 Lock 기능을 제공하는 것이 atomic

 

따라서 쓰레드1이 name이란 프로퍼티에 값을 쓰는 중이면,

다른 쓰레드들은 name이란 프로퍼티에 접근할 수 없음 Lock이 걸려있기 때문에

(Lock이 풀릴 때 까지 그대로 멈춰있음)

 

오호? 그럼 자동으로 mutex가 되는 거니

무조건 atomic 쓰는 게 좋은 거 아니야?? 라고 생각할 수 있지만,

 

atomic으로 선언할 경우 안전해 보이긴 하지만,

그만큼 성능 저하가 일어남 프로퍼티가 많아질 수록 더 심각해지겠징?

 

따라서, 멀티 쓰레딩 환경에서 꼭 보호받아야 하는 경우가 아니면

성능 저하를 막기 위해 nonatomic으로 명시해주어야 함

 

 

@property (nonatomic) NSString *name;
 

 

 

아 참고로 Swift는 thread-safe를 고려하지 않고 만든 언어라

default 값이 nonatomic이라고 함!!

(별도로 atomic을 지정할 수도 없고, GCD로 구현해야 한다 함)

 

 

 

 

4. retain / assign / weak / strong / copy

 

자.... 속성들이 좀 많네 .. 🌚

이것에 대한 이해를 하기 위해선 ARC를 먼저 이해하고 오셔야 함!!

왜냐면 이번 속성들은 ARC와 관련이 있기에 :)

ARC를 안다는 가정 하에 설명 하겠음

 

먼저 Objective-C는 ARC가 나오기 전부터 쓰던 언어임

따라서 MRC라는 것이 존재 했는데,  이 MRC에서 사용하던 것이 바로

 

retain

assign

 

이라는 것들임!

근데 이제 Objective-C도 대부분 ARC만 사용하니 이 둘은 거의 사용하지 않음

왜냐면 ARC 속성들이 Objective-C에도 생겼거든!!!!

따라서 MRC와 ARC 속성들이 공존해서 헷갈릴 수 있는데 어떻게 이해를 하면 좋냐면,

 

retain / strong : Swift에서strong에 해당한다. Reference Count를 증가시킨다.

weak : Swift에서 weak에 해당한다. Reference Count를 증가시키지 않는다.

참조하던 객체가 메모리에서 해제될 경우 자동으로 nil이 할당된다

assign : Swift에서 unowned에 해당한다. Reference Count를 증가시키지 않는 건 weak와 동일하나,

참조하던 객체가 메모리에서 해제될 경우, 해제된 주소값을 계속 갖고 있다 (따라서 해제 후 접근 시 앱 사망~~)

 

이렇게 ARC와 비교해서 보면 어렵지 않음 :)

비록 아직 MRC의 잔재인 retain & assign이 남아 있지만,

ARC만 지원하는 Swift처럼 strong, weak, assign(unowned)로 사용하면 될 것 같음!

 

 

움... 헷갈릴 수 있는

weak / assign의 차이점을 예제로 보여드리자면,

 

 

@property (weak) NSArray *array1;
 

 

 

이렇게 weak로 선언한 경우, 

 

 

NSArray *array2 = [[NSArray alloc] initWithObjects:@"Sodeul"nil];
array1 = array2;
array2 = nil;
NSLog(@"array1 == %@", [array1 firstObject]);
 

 

 

참조하고 있던 객체를 메모리에서 해제시켜 버리면

(Reference Count를 증가시키지 않으니 바로 해제됨)

 

 

 

 

 

array1은 이렇게 nil 값을 가지며 에러가 발생하지 않음

근데, 만약 다음과 같이 assign으로 선언해주면

 

 

@property (assign) NSArray *array1;
 

 

 

똑같이 위의 코드를 실행 시켰을 때

 

 

 

 

이미 해제된 array2의 주소값을 계속 들고 있어서,

해제된 메모리에 접근하여 에러가 남!!

 

따라서, 웬만해선 안전한 weak를 쓰자 :)

 

....

저기요... 아직 copy 안했어요....

모르겠어요..... 아무리 찾아봐도 이해가 잘 안돼요.. 흑흑

NSCopying 프로토콜을 준수해야만 사용 가능하고, 복사본을 만든다는데

테스트 할땐 원본 받던데요 흑흑

 

copy는 제가 제대로 이해 했을 때 다시 추가 하겠음 흑흑

 

 

 

 

5. nonnull / nullable

 

이 속성은 Swift의 Optional을 나타내기 위해 도입한

Objective-C의 속성이라고 보면 됨 :D (따 라 쟁 이 👀)

 

nonnull = Non-Optional Type

nullable = Optional Type

 

근데 Swift처럼 엄청 민감하게 nonnull인데 nil 할당 한다고

막 에러 내고 그런 정도는 아니구 귀엽게 노란 warning 정도를 해줌!!!

 

 

@property (nonnull) NSString *strNonnull;
@property (nullable) NSString *strNullable;
 

 

 

이렇게 선언했을 경우,

외부에서 이 값들에 nil을 대입하면

 

 

 

 

nullable의 경우 warning이 안 뜨지만,

nonnull의 경우 warning이 뜹니다 :)

 

 

 

 

.

.

.

그 외에 3개 정도 더 있긴 한데 (unsafe 어쩌고)

실제 사용할 일은 거~~~~~~의 없어서 나중에 하게되면 추가 하겠음 :)

피드백 환영~~~~~~~~

 

 



Calendar
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
최근 댓글
Visits
Today
Yesterday