안녕하세요 :) 소들입니다!!
이번 포스팅에선 프로퍼티의 속성에 대해 공부하려고 해요
음.. 속성이 뭐냐고 묻는다면 프로퍼티를 생성할 때 생략해도 되지만,
이런 식으 () 안에 프로퍼티의 속성을 지정할 수 있어요!
오늘은 프로퍼티엔 어떤 속성들이 있고,
어떤 것들을 지정할 수 있는지 봐볼 거예요 :)
모든 포스팅은 편의 말투로 합니다~!!
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 어쩌고)
실제 사용할 일은 거~~~~~~의 없어서 나중에 하게되면 추가 하겠음 :)
피드백 환영~~~~~~~~
'iOS > Objective-C' 카테고리의 다른 글
Objective-C) 프로퍼티 (1/2) - 인스턴스 변수와 프로퍼티 (8) | 2020.12.06 |
---|---|
Objective-C) Category와 Extension (4) | 2020.12.06 |
Objective-C) JSON을 Decoding 해보자 (4) | 2020.12.05 |
Objective-C) JSON을 Encoding 해보자 (0) | 2020.12.04 |
Objective-C) C++ 사용하기 (0) | 2020.12.02 |