일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Large File Storage
- 잡초가득블로그
- Dispatch.main.sync
- memory safety
- 로버트마틴형
- windowScene
- Concurrent
- iOS 버전 점유율
- in-out
- coordinateSpace
- conflicting access to memory
- RxSwift
- iOS Target
- SWIFT
- RxCocoa
- UICoordinateSpace
- Apple Certificate
- Ribs
- ios
- swiftdocs
- 대머리깃허브
- Git Large File Storage
- 메모리 접근 충돌
- App Signing
- Automatically manage signing
- rib
- 클린아키텍쳐
- RIBs Tutorial
- Dependency Rule
- Github file size
- Today
- Total
빙수왕의 개발일지
In-Out Parameters, 인아웃 파라미터에 대하여 본문
Swift Docs를 기반으로 이해한 내용을 작성하였습니다.
In-Out Parameters
함수 파라미터는 default가 상수이다.
상수이므로, 함수 parameter의 값을 함수의 body 안에서 바꾸려고 하면 compile-time 에러가 발생.
parameter의 값을 변경하고 싶다면, 그리고 이 변경이 함수 호출이 끝나고도 지속되길 원한다면, 파라미터를 in-out
parameter로 만들어라.
in-out
키워드는 parameter 앞에 배치하여 사용한다.
in-out
매개변수에는 함수에 전달되고, 함수에 의해 수정되고, 원래 값을 대체하기 위해 함수 외부로 다시 전달되는 값이 있다.
상수나 문자(literal value)는 argument(전달인자)로 사용될 수 없다. (수정할 수 없는 값이기 때문에)
함수를 콜할 때, 변수의 이름 바로 앞에 앰퍼샌드(&)를 배치한다.
in-out 파라미터는 default 값을 가질 수 없다.
variadic 파라미터(가변 파라미터)는 inout 으로 표시할 수 없다.
예제
아래 예제에서, swapTwoInts(::)를 통해 someInt와 anoterInt의 값이 바뀐걸 알 수 있다.
in-out 파라미터는 함수에서 값을 return하는것과 다르다.
in-out 파라미터는 함수가 함수의 body 범위 밖에서 영향을 발휘하는 방법 중 하나이다.
In-Out Parameters 의 최적화
In-Out parameter들은 다음 과정을 통해 전달된다:
- 함수가 호출되면, argument의 값이 복사된다.
- 함수의 body 안에서, 아까 복사된 복사본이 변경된다.
- 함수가 return할 때, 복사본이 원래 argument에 할당된다(assigned).
이 동작을 copy-in copy-out
또는 call by value result
라고 한다. 예를 들어, 계산 속성(computed property) 또는 observer를 가진 프로퍼티가 in-out
파라미터로 전달되면, 함수가 호출 될 때 getter, 함수가 return될 때 setter가 호출될 것이다.
→ 함수에 들어갈 때 그 값이 copy 되기 때문에 getter가 호출되고, 함수가 리턴될 때 copy되어 변형된 값을 다시 원래 프로퍼티에 넣어주므로 setter가 호출된다는 뜻인듯함.
최적화에서(As an optimization), argument가 메모리의 물리적 주소에 저장된 값일 때, 같은 메모리 위치(location)는 함수 body의 안과 밖 모두에서 사용된다. 이 최적화 동작을 call by reference
라고 한다. call by reference
는 복사의 오버헤드(코스트 정도로 받아들이면 될듯)를 제거하면서 모든 copy-in copy-out
모델의 모든 요구사항을 만족한다. copy-in copy-out
에서 제공하는 모델을 사용하여 코드를 짜쇼. call by reference
에 의존하지 마시고요. 그래서 이게 최적화 여부와 관계없이 올바르게 동작할 수 있도록 하십쇼.
→ 이부분 너무 이해가 안돼서 20번도 넘게 읽은거같다.. ㅎ 근데도 아직 잘 모르겠다. 여기서 말하는 최적화라는건, 컴파일 속도에 대한 최적화인 것 같다.(Swift Optimization 구글에 검색했더니 '컴파일러'의 Optimization에 관한 내용, 방법들만 나오니 그런것으로 간주하는중) Project의 Build Setting에 보면 최적화 레벨을 설정할 수 있는데 이에 따라 컴파일 속도가 달라진다.(아래 캡쳐에 있음) 이 최적화 레벨에 따라 call by reference가 될 수도 안될수도 있기 때문에(아마도 최적화 레벨을 올리면 inout키워드로 쓰인 파라미터가 copy-in copy-out이 아닌, call by reference로 진행된다는 것 같음), 이 최적화 레벨과 상관없이 잘 동작하도록 in-out 키워드를 잘 쓰라는 말인 것 같다.
그럼 call by reference는 그럼 무적권 좋은가? 쓸데없이 copy하지 않아 메모리 관점에서는 이득이겠지만, 아마 이 reference로 사용할 때 동일한 주소에 접근하지 않도록 뭔가 .. lock하는 과정이 있을 것 이므로 항상 최고다라고는 할 수 없겠다. 하지만 swift에서 최적화 옵션을 높이면 call by reference를 한다니까 아마 이득이니까 그럴듯?
함수 내에서는, 원래 값이 현재 범위(scope)에서 사용이 가능하더라도 in-out
argument로 전달된거에 access 하지 마쇼. 원본에 access하는 것은 동시(simultaneous) 액세스임. 이것은 스위프트의 메모리 독점성 보장(Swift’s memory exclusivity guarantee)을 위반한다. 같은 이유로, 당신은 여러 in-out
파라미터에 같은 값을 전달할 수 없다.
→ 전달된 argument의 original에 한번에 한놈만 접근하자.
→ 맨 마지막 줄은 한 함수에 여러 in-out 파라미터가 있을 때, 여러 파라미터에 같은 argument를 전달할 수 없다는.. 뜻..인듯..
→ Memory Safety는 멀티쓰레드 환경에서 다양한 쓰레드가 한곳에 접근해도 값이 이상하게 변하지 않음을 보장하는 것이다. 더 자세한 내용은 아래 링크 참조. (다음에 봐야겠다.ㅎ)
https://docs.swift.org/swift-book/LanguageGuide/MemorySafety.html
클로저나 중첩 함수(nested function)에서 사용할 땐 in-out
파라미터가 nonescaping
이여야 합니다.
만약 캡처를 해야한다면, 캡처 리스트
를 사용하세요. 캡처 후 값을 변경해야 한다면, 명시적인 local 복사본을 만들어서 함수 return 전에 원래 변수에 넣는 작업을 구현해야 합니다.
→ 위 코드에서는 중첩 함수에서 원래의 a가 변경되지 않도록 캡쳐 리스트를 사용하고 있다.
→ 위 코드는 명시적인 local 복사본을 만들고, defer을 통해서 원래 변수에 넣어주고 있다.
출처
https://docs.swift.org/swift-book/LanguageGuide/Functions.html
https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID545
'개발 > iOS' 카테고리의 다른 글
앱만들기 #1 - iOS Deployment Target 정하기 (0) | 2021.08.15 |
---|---|
Memory Safety - #1 Conflicting Access to Memory (0) | 2021.08.05 |
RxSwift 테이블뷰 다시 바인드할 때 오류 (0) | 2021.07.08 |
info.plist 이동 후 해야할 작업 (0) | 2021.06.25 |
RxSwift, RxCocoa, RxRelay의 Observable, Subject, Driver, Signal, Relay 표로 정리 (0) | 2021.06.24 |