ㄷㅣㅆㅣ's Amusement
[swift] getter/setter, subscript, property wrapper에서 get/set의 상이한 동작 본문
Programming/iOS
[swift] getter/setter, subscript, property wrapper에서 get/set의 상이한 동작
ㄷㅣㅆㅣ 2020. 6. 18. 15:57[swift] getter/setter, subscript, property wrapper에서 get/set의 상이한 동작
반응형
개발하다 보면 "당연히 이러하겠지"라고 생각했다가 낭패를 보는 경우가있다.
오늘도 낭패를 봤기 때문에 하나씩 정리해 나가기로 하였다.
- getter/setter, subscript, property wrapper에서의 get/set.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 1. get/set struct Getset { private var _value = 0 var value: Int { get { print("get") return _value } set { print("set") _value = newValue } } } var getset = Getset() getset.value = 10 // ---------- // set | cs |
당연히도 위의 코드의 결과는 set한번 찍히는 것이 전부다.
그런데 다음의 코드를 보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | struct Getset { private var _value = [String: String]() var value: [String: String] { get { print("get") return _value } set { print("set") _value = newValue } } } var getset = Getset() getset.value["dog"] = "Marc" // ---------- // get // set | cs |
이 코드는 get이 먼저 출력된 다음 set이 출력된다.
왜일까????
일단 접어두고, Property Wrapper로 Atomic을 다음과 같이 만들어보자.
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 | @propertyWrapper struct Atomic<Value> { private var value: Value private let queue = DispatchQueue(label: "atomic_queue") init(wrappedValue value: Value) { self.value = value } var wrappedValue: Value { get { return load() } set { store(value: newValue) } } func load() -> Value { return queue.sync { () -> Value in print("get") return value } } mutating func store(value: Value) { queue.sync { print("set") self.value = value } } } | cs |
그리고 Dictionary와 Int 에 적용해보면, getter/setter와 마찬가지로 dictionary는 get,set을 연달아 출력하고, Int는 set만이 출력된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class TestClass { @Atomic var animals = [String: String]() @Atomic var count = 0 func test() { animals["dog"] = "Marc" count = 10 } } var testClass = TestClass() testClass.test() // ---------- // get // set // set | cs |
작성된 @Atomic이 type에 영향을 받는다.
그런데 사실이러한 상황은 이미 인지하고 있었고 Atomic사용에 대한 회의감을 느끼고 있었기에 이것은 오늘의 낭패가 아니다.
놀라운 일은 이 다음부터다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | struct Animals { private let queue = DispatchQueue(label: "animal_queue") private var animals = [String: String]() subscript(kind: String) -> String? { get { print("get") return queue.sync { animals[kind] } } set { print("set") queue.sync { animals[kind] = newValue } } } } var animals = Animals() animals["dog"] = "marc" // ---------- // set | cs |
위의 코드에서는 set만이 출력된다.
형태가 같다고해서 동작이 같지는 않다
반응형
'Programming > iOS' 카테고리의 다른 글
WWDC 2018 (0) | 2018.08.21 |
---|---|
[Swift] How to convert from void* to char* (0) | 2017.09.05 |
How to use private git repository under carthage. on Mac OS (0) | 2017.08.22 |
[iOS/Objective-C] Audio Player tutorial using AVPlayer (AVFoundation) -- 1 (0) | 2016.02.24 |
[iOS/Objective-C] Video Player tutorial using AVPlayer (AVFoundation) (2) | 2016.02.23 |
Comments