티스토리 뷰

반응형

안녕하세요 :) Zedd입니다.

오늘은 Realm하면서.....자주...보이는...

dynamic var..

var는 알겠는데 도대체 이 dynamic이 왜 앞에 붙을까요?

오늘은 dynamic에 대해서 알아봅시다.



dynamic



dynamic이 사용되는 이유는 바로 Swift와 Objective-C와의 상호운용성(Interoperability)때문인데요,

Swift와 Objective-C가 같이 잘 작동한다고 해도, Objective-C의 모든 기능을 Swift에서 사용할 수 있는 것은 아니에요.

Objective-C는 강력한 언어이며, 그 힘의 대부분은 Objective-C 런타임의 결과입니다.

예를들어, 동적 디스패치(dynamic dispatch) 는 Objective-C를 동적으로 만드는 기능 중 하나입니다.

이는 Objective-C 런타임이 호출해야하는 특정 메소드나 함수의 구현을 런타임에 결정한다는 것을 의미합니다. 

예를들어, 하위 클래스가 슈퍼 클래스의 메소드를 재정의(override)하는 경우, 동적 디스패치는 메소드의 구현을 호출해야하는지, 하위 클래스의 메소드 또는 부모클래스의 메소드를 호출해야하는지를 파악합니다. 이것은 매우 강력한 개념(concept)입니다. (강력하다고 좋다는건 아님zzz)


Swift는 가능할 때마다 Swift 런타임을 사용합니다. 

그 결과 여러가지 최적화 작업을 수행할 수 있습니다. 

Objective-C는 동적 디스패치만을 사용하지만, Swift는 다른 선택이 없으면, 동적 디스패치를 선택할 뿐입니다. 만약 컴파일러가 컴파일타임에 선택할 수 있는 메소드의 구현을 파악할 수 있다면, 동적 디스패치를 선택하지 않고도, 수 나노초에 이길것입니다( it wins a few nanoseconds).



자..이까지 읽어보면 정말 이해가 1도 안가는 것을 알 수 있습니다 :)

간단하게?..설명해드릴게요.

Objective-C는 클래스의 메소드나 프로퍼티를 호출할 때, 해당 객체에 "메세지"를 보내는 방식(message sending)으로 구현되어있어요. 내가 zedd라는 메소드 실행해줘! 라고 하면, 

일단 그 클래스의 객체한테 "zedd메소드 실행"이라는 메세지를 보내요. 

[anObject doMethod:aParameter];



이런식으로..보낸다고 합니다. 


그럼 메세지를 받은 객체는 이제 진짜 그 메소드가 구현되어있는 곳으로 가서 비로소 그 메소드를 실행하는거죠. 

objc_msgSend(anObject, @selector(doMethod: ), aParameter)


가장 중요한 것은 이러한 과정이 "런타임"에 일어난다는 것이죠.

자, 그럼 생각해봅시다.


매번 실행할때, 그제서야 객체가 메세지받고, 그리고 그 해당 메소드 구현된 곳 가서 실행하고...그럼 음...저는 좋아보이진 않네요. 일단 성능측면에서요 :) 당연히 성능이 저하되겠죠?

"컴파일타임"에 해당 메소드의 실제 코드 위치를 알면 그 메소드가 어딨는지 찾을 필요도 없고, 바로 그 주소로 점프해서 실행하면 되겠죠?

이럴경우, 컴파일러의 최적화가 가능하다고 합니다. 이게 바로 정적(static) 디스패치에요. 당연히 정적 디스패치가 더 빠르겠죠?

실제로 Increasing Performance by Reducing Dynamic Dispatch 라는 글이 애플에 올라와있답니다 :)


그럼 동적 디스패치가 안좋냐? 왜있냐? 왜쓰냐????
일단 한가지 사실을 알 수 있을 것 같군요.
dynamic var또는 dynamic func..이 의미하는 바는 아 얘는 Swift런타임말고 Objective-C런타임 쓸게~~~ 
== 객체한테 메세지보내고 -> 객체가 메소드 위치 찾아서 실행할게~~~!
가 되는군요.

동적 디스패치가 이런식으로 스텝을 거쳐서 실행되는데, 왜 쓰냐?
동적 디스패치도 쓰일데가 있어서 있겠죠?
코어데이터나 키-밸류 옵저빙(KVO = Key-Value Observing)과 같은 것들은 동적인  Objective-C런타임 덕분에 가능하답니다 :)

dynamic에 대해 조금 더 말씀드리자면,
선언앞에 dynamic 키워드를 붙히면, objc속성이 암시적으로 표시된다고 해요.
그리고 dynamic키워드는 오직 Class의 멤버에만 사용될 수 있어요.
구조체와 열거형은 상속을 지원하지 않죠? 즉!!!!!!!! 런타임이 사용할 필요가 있는 구현을 파악할 필요가 없음을 의미합니다!!!!!!!!위에서 그랬죠?


"예를들어, 하위 클래스가 슈퍼 클래스의 메소드를 재정의(override)하는 경우, 동적 디스패치는 메소드의 구현을 호출해야하는지, 하위 클래스의 메소드 또는 부모클래스의 메소드를 호출해야하는지를 파악합니다."


자..dynamic에 대해서 좀 아시겠나요?

그럼..제 궁금증의 원인 

위 코드는 Realm 튜토리얼에 있어요. 

자..왜 하필 dynamic일까....

그냥 var...안되나...


Realm을 사용하실려면, 평범한 var 프로퍼티에는 dynamic이 "필수"라고 합니다. 자세한 사항은 Realm 공식 문서를 참고해주세요.

프로퍼티가 기본 데이터베이스 데이터에 대한 접근자가 될 수 있도록, Realm모델 프로퍼티에는 @objc dynamic var 프로퍼티가 필요합니다.

(저 튜토리얼이 옛날거라 그런가..? @objc는 없네요. 근데 dynamic을 사용하면 암시적으로 @objc가 붙은 효과가 나는데..꼭 붙혀줘야 하는건가요?..)

클래스가 @objcMembers(Swift 4이상)로 선언되어 있으면 개별 프로퍼티를 dynamic var로 선언할 수 있습니다.


"dynamic키워드는 모델 변수에 대한 변경 사항을 Realm에 알리고, 결과적으로 이를 데이터베이스에 반영할 수 있도록 허용합니다."

라고 하네요. 이것이 Realm에서 dynamic을 사용해야하는 핵심이겠죠? 


흐음..왜 튜토리얼은 @objc가 안붙어있는지..납득이 잘 안가지만......아무튼 Realm에서 dynamic이 쓰이는 이유를 알았으니 ㅎㅎ..

dynamic에 대해 이해가 좀 가시나요??!

저는 Objective-C를 잘 몰라서..메소드를 호출하는 방식이라던가..신기했네요 :) 

아무튼 도움이 되었으면 좋겠습니다 XD..



https://outofbedlam.github.io/swift/2016/01/27/Swift-dynamic/

https://www.slideshare.net/YongHaYoo/ss-63881606

https://cocoacasts.com/what-does-the-dynamic-keyword-mean-in-swift-3

를 참고하였어요 :)



반응형

'Swift' 카테고리의 다른 글

Swift ) Unicode to Int/Int to Unicode  (2) 2017.12.14
Swift ) Nested Types  (0) 2017.12.06
Swift ) Patterns  (0) 2017.10.31
Swift ) Type Casting  (2) 2017.10.23
Swift ) Protocols (2)  (3) 2017.10.18