์๋ ํ์ธ์, ๊ฐ์์ ๋๋ค. ์ค๋์ property์ ๋ํด์ ๊ณต๋ถํด๋ณด์์ต๋๋ค. ํ๋กํผํฐ ๊ฐ๋ ์ ๊ณต๋ถํ๋ฉด์ ์ฐธ ๋ชจํธํ๊ณ ์ดํด๊ฐ ๊ฐ์ง ์์๋ ๋ถ๋ถ์ด ๋ง์๋๋ฐ์, ์ด๋ฐ ๋ถ๋ถ์ ๋ํด์๋ ์ถํ์ ํ๋กํผํฐ ์ ๋ณตํ๊ธฐ ํฌ์คํ ์ ๋ค์ ํ ๋ฒ ํด์ผํ ๊ฒ ๊ฐ์์. ์ผ๋จ ๊ธฐ์ด๊ฐ๋ ์ ์ก์ ์ ๋ฆฌ๊ธ ์ ๋๋ก ๋ด์ฃผ์ธ์! ์์ํฉ๋๋ค.
Swift Document chap.10 Properties ๋ฐ๋ก๊ฐ๊ธฐ
Properties (ํ๋กํผํฐ)
ํด๋์ค๋ ๊ตฌ์กฐ์ฒด, ์ด๊ฑฐ์ฒด์ ๊ฐ์ฒด ์ธ์คํด์ค๊ฐ ๊ทธ ๋ด๋ถ์ ๊ฐ์ง๊ณ ์๋ ๊ฐ์ฒด์ ์ํ์ ๊ดํ ์ ๋ณด๋ฅผ ๋งํ๋ค.
ํ๋กํผํฐ ์ข ๋ฅ
- Stored Property (์ ์ฅํ๋กํผํฐ)
- ์ธ์คํด์ค์ ์ผ๋ถ๋ถ์ผ๋ก์จ ์์์ ๋ณ์ ๊ฐ์ ์ ์ฅํจ
- ํด๋์ค์ ๊ตฌ์กฐ์ฒด์์๋ง ์ ๊ณตํจ
- Computed Property (๊ณ์ฐ ํ๋กํผํฐ)
- ๊ฐ์ ๊ณ์ฐํ๋๋ฐ ์ฐ์ด๋ ํ๋กํผํฐ
- ํด๋์ค, ๊ตฌ์กฐ์ฒด, ์ด๊ฑฐํ์์ ์ ๊ณตํจ
- Type Property (ํ์
ํ๋กํผํฐ)
- ํ๋กํผํฐ๋ ํ์ ๊ทธ ์์ฒด์ ์ฐ๊ฒฐ๋์ด ์์ ์ ์๋๋ฐ, ์ด๋ฅผ ํ์ ํ๋กํผํฐ๋ผ๊ณ ํจ
Property Observer (ํ๋กํผํฐ ์ต์ ๋ฒ)
- ํ๋กํผํฐ๊ฐ ๊ฐ์ง ๊ฐ์ ๋ณํ๋ฅผ ๊ด์ฐฐํ๊ธฐ ์ํจ
- ์ ์ํ ํ๋กํผํฐ๋ ํ์ ํด๋์ค๊ฐ ์์๋ฐ๋ ์์ํด๋์ค์ ์ถ๊ฐํ ์ ์๋ค.
Property Wrapper
- ํ๋กํผํฐ wrapper๋ฅผ ์ฌ์ฉํ๋ฉด ํ๋กํผํฐ์ getter, setter๋ฅผ ์ฌ์ฉํ์ฌ ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉํ ์ ์์.
Stored Properties (์ ์ฅ ํ๋กํผํฐ)
ํด๋์ค๋ ๊ตฌ์กฐ์ฒด์ ์ธ์คํด์ค์ ์ผ๋ถ๊ฐ ๋๋ ์์๋ ๋ณ์์ด๋ค. let์ผ๋ก ์ ์ธ๋์๋ var๋ก ์ ์ธ ๋์๋์ ๋ฐ๋ผ ์์, ๋ณ์ ์ค ์ด๋ค ๊ฒ์ผ๋ก ์ ์ธ ๋์๋์ง ์ ์๋๋ค.
๋ํ ์ ์ฅ ํ๋กํผํฐ๋ฅผ ์ ์ธํ ๋ ์ ์ฅํ “๊ธฐ๋ณธ๊ฐ (Default Property Value)”๋ฅผ ์ค ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๋ฌํ ์ ์ฅ ํ๋กํผํฐ๋ initializer(์์ฑ์)๋ก ์ด๊ธฐํ ์ํฌ ์ ๋ ์๋ค. ์์ฑ์์ ์ํด ์ด๊ธฐํ ๋ ๋๋ ํด๋น ํ๋กํผํฐ๊ฐ ์์๋ก ์ ์ธ ๋์๋ค๊ณ ํด๋ ์์ ์ด ๊ฐ๋ฅํ๋ค.
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
// ์ด ๋ฒ์๋ ์ ์ ๊ฐ 0, 1, 2 ๋ฅผ ๋ํ๋
rangeOfThreeItems.firstValue = 6
// ์ด์ ๋ฒ์๋ ์ ์ ๊ฐ 6, 7, 8 ์ ๋ํ๋
์ ์ฝ๋๋ ์์ฑ ํ์๋ ๊ธธ์ด๋ฅผ ๋ฐ๊ฟ ์ ์๋ length ์์๋ฅผ ํฌํจํ ๊ตฌ์กฐ์ฒด์ด๋ค.
Stored Properties of Constant Structure Instances
๊ตฌ์กฐ์ฒด ์ธ์คํด์ค๋ฅผ ์์๋ก ์ ์ํ๋ค๋ฉด, ์์ฑ๊ณผ ๋์์ ์ด๋ค ํ๋กํผํฐ๋ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๊ฒ ๋๋ค.
let rangeOfFourItems = FixedLengthRange(firstValue : 0, length: 4)
// ์ด ๋ฒ์๋ ์ ์ ๊ฐ 0, 1, 2, 3 ์ ๋ํ๋
rangeOfFourItems.firstValue = 6.
//ERROR!!!!
// ์ด๋, firstValue ๊ฐ ๋ณ์ ์์ฑ์ผ์ง๋ผ๋, ์๋ฌ๋ฅผ ๋ณด๊ณ ํ ๊ฒ์
์ ์ฝ๋๋ฅผ ๋ณด๋ฉด, firstValue๋ผ๋ ํ๋กํผํฐ๋ ๊ตฌ์กฐ์ฒด๋ฅผ ์ ์ธํ ๋ ๋ณ์๋ก ์ ์ธ๋์์ง๋ง, ๊ตฌ์กฐ์ฒด ์ธ์คํด์ค์ธ rangeOfFourItems ๋ ์์๋ก ์ ์ธ๋์๊ธฐ ๋๋ฌธ์ rangeOfFourItems๋ ๋ณ๊ฒฝํ ์ ์๊ฒ ๋๋ค. ์ด๋ฌํ ๊ฒฐ๊ณผ๊ฐ ๋์ค๋ ์ด์ ๋ ๊ตฌ์กฐ์ฒด๊ฐ ๊ฐํ์ ์ด๊ธฐ ๋๋ฌธ์ด๋ค. ๊ตฌ์กฐ์ฒด ์ธ์คํด์ค๋ฅผ ์์๋ก ์ ์ธํ๊ฒ ๋๋ฉด ๋ด๋ถ์ ํ๋กํผํฐ๋ค๋ ๋ชจ๋ ์์๊ฐ ๋์ด ์์ ํ ์ ์๊ฒ ๋๋ค.
ํ์ง๋ง, ์ฐธ์กฐํ์ ์ธ ํด๋์ค์์๋ ์ด๊ฒ๊ณผ ๋ค๋ฅธ ๊ฒฐ๊ณผ๊ฐ ๋ํ๋๋ค. ํด๋์ค ์ธ์คํด์ค๋ฅผ ์์๋ก ์ ์ธํด๋ ์ ์ธํ ํ๋กํผํฐ์ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ค.
class FixedLengthRange {
var firstValue: Int
let length: Int
init(firstValue: Int, length: Int) {
self.firstValue = firstValue
self.length = length
}
}
let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
// ์์๋ก ์ ์ธ๋ ํด๋์ค ์ธ์คํด์ค๋ ๋ณ์๋ก ์ ์ธ๋ ํ๋กํผํฐ์ ๊ฐ์ ๋ฐ๊ฟ ์ ์์ต๋๋ค.
rangeOfFourItems.firstValue = 5
// ์ค๋ฅ ๋ฐ์! rangeOfFourItems.length = 3
Lazy Stored Properties
Lazy ์ ์ฅ ํ๋กํผํฐ๋ ํ๋ง๋๋ก ๋งํด์, ๊ฐ์ด ์ฌ์ฉ๋๊ธฐ ์ ๊น์ง๋ ๊ฐ์ด ๊ณ์ฐ๋์ง ์๋ ํ๋กํผํฐ ์ด๋ค. ์ด ํ๋กํผํฐ๋ lazy๋ผ๋ ํค์๋๋ฅผ ์ฌ์ฉํด์ ์ ์ธํ ์ ์๋ค. lazy ํ๋กํผํฐ๋ ๋ฐ๋์ var ๋ณ์๋ก ์ ์ธํด์ผํ๋ค. ๋ณ์๋ก ์ ์ธํ์ง ์๊ฒ ๋๋ฉด ์ฒ์ ์ฌ์ฉํ ๋๊น์ง ๊ฐ์ด ์๊ฒ ๋๊ธฐ ๋๋ฌธ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ฒ ๋๋ ๊ฒ์ด๋ค.
์ธ์ ์ฌ์ฉํ๋ฉด ๋๋?
lazy ์ ์ฅ ํ๋กํผํฐ๋ ์ด๊ธฐ๊ฐ์ด ์ธ์คํด์ค ์ด๊ธฐํ๊ฐ ๋ ๋๊น์ง ๊ฐ์ ๋ชจ๋ฅด๋ ์ธ๋ถ์์์ ์์กดํ๋ ๊ฒฝ์ฐ์ ์ ์ฉํ๊ฒ ์ฌ์ฉ๋๋ค. ๋ํ, ์ด๊ธฐ๊ฐ์ด ๋ณต์กํ๊ฑฐ๋, ๊ณ์ฐ๋น์ฉ์ด ๋ง์ด ๋๋ ์ค์ ์ ํ์๋ก ํ ๋๋ ์ ์ฉํ๊ฒ ์ฌ์ฉ๋๋ค.
class DataImporter {
/*
DataImporter ๋ ์ธ๋ถ ํ์ผ์์ ์๋ฃ๋ฅผ ๋ถ๋ฌ์ค๋ ํด๋์ค์
๋๋ค.
์ด ํด๋์ค์ ์ด๊ธฐํ์๋ ์ ์๋ฏธํ ์์ ์๊ฐ์ด ๊ฑธ๋ฆฐ๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
*/
var filename = "data.txt"
// DataImporter ํด๋์ค๋ ์ฌ๊ธฐ์ ์๋ฃ ๋ถ๋ฌ์ค๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ ๊ฒ์
}
class DataManager {
lazy var importer = DataImporter()
var data = [String]()
// DataManager ํด๋์ค๋ ์ฌ๊ธฐ์ ์๋ฃ ๊ด๋ฆฌ ๊ธฐ๋ฅ์ ์ ๊ณตํ ๊ฒ์
}
let manager = DataManager()
// DataManager์ ์ธ์คํด์ค๋ฅผ ๋ง๋ฆ.
// ์ฐธ๊ณ ๋ก, DataManager์ ์ ์ฅํ๋กํผํฐ๋ค์ ์ด๊ธฐ๊ฐ์ด ์์ผ๋ฏ๋ก init์ด ์์ด๋ ๋จ
manager.data.append("Some data")
manager.data.append("Some more data")
// ํ์ง๋ง ์์ง๋ importer ์์ฑ์ DataImporter ์ธ์คํด์ค๋ ์์ง ์์ฑํ์ง ์์
// -> lazy ์ด๊ธฐ ๋๋ฌธ
์ ์ฝ๋์์ importer ๋ผ๋ DataImporter ์ธ์คํด์ค๋ lazy ์ ์ธ์ด ๋์๋ค. ํ์ง๋ง ๋ฐ์์ manage๋ผ๋ Datamanager์ ์ธ์คํด์ค๋ฅผ ์ด์ฉํด importer์ ํ๋ฒ๋ ์ ๊ทผ์ ํ์ง ์์๋ค. lazy๋ก ์ ์ธํ์ง ์์๋ค๋ฉด, importer๊ฐ ์์ฑ์ด ๋์๊ฒ ์ง๋ง, lazy๋ก ์ ์ธ๋์๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ๋๊ธฐ ์ ๊น์ง๋ ์์ฑํ์ง ์๋ ๊ฒ์ด๋ค.
Stored Properties and Instance Variables
Objective-C ์ธ์ด์์๋ ๊ฐ์ ์ ์ฅํ๊ธฐ ์ํด ์ ์ฐ์ฐ์(instance.property = value)๋ set์ฐ์ฐ์(instance.setProperty(value))์ผ๋ก ๊ฐ์ ์ ์ฅํ๋ค. ๋ฟ๋ง ์๋๋ผ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ์ ๊ด๋ จํ ๊ฐ๋ ๋ ํ๋กํผํฐ์ ํจ๊ป ๋ช ์ํ๋ค. (@property (nonatomic, retain) NSString*propertyName;)
Swift์์๋ ์ด๋ฐ ์ปจ์ ์ ํ๋์ ํ๋กํผํฐ์ ๋ น์ฌ ์ ์ธ๊ณผ ์ฌ์ฉ์ ํผ๋์ ์ค์๋ค. ํ๋กํผํฐ์ ์ด๋ฆ, ํ์ , ๋ฉ๋ชจ๋ฆฌ๊ด๋ฆฌ ๋ฑ์ ๋ชจ๋ ์ ๋ณด๋ฅผ ํ๋กํผํฐ๋ฅผ ์ ์ธํ๋ ํ ๊ณณ์์ ์ ์ํ๊ฒ ๋๋ค!
Computed Properties (์ฐ์ฐ ํ๋กํผํฐ)
ํด๋์ค, ๊ตฌ์กฐ์ฒด, ์ด๊ฑฐํ์ ๊ณ์ฐ๋ ํ๋กํผํฐ๋ฅผ ์ ์ธํ ์ ์๋ค. ์ด ์ฐ์ฐํ๋กํผํฐ๋ ์ค์ ๊ฐ์ ์ ์ฅํ๊ณ ์๋ ๊ฒ์ด ์๋๋ผ, getter๊ณผ optionalํ setter๋ฅผ ์ ๊ณตํด ๊ฐ์ ํ์ํ๊ณ ๊ฐ์ ์ ์ผ๋ก ๋ค๋ฅธ ํ๋กํผํฐ ๊ฐ์ ์ค์ ํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ค. setter๋ ํ์์ ์ธ ์์๋ ์๋๊ณ ์ ํ์ฌํญ์ด๋ค.
struct Point {
var x = 0.0, y = 0.0
}
struct Size {
var width = 0.0, height = 0.0
}
struct Rect {
var origin = Point()
var size = Size()
var center: Point {
get {
let centerX = origin.x + (size.width / 2)
let centerY = origin.y + (size.height / 2)
return Point(x: centerX, y: centerY)
}
set(newCenter) {
origin.x = newCenter.x - (size.width / 2)
origin.y = newCenter.y - (size.height / 2)
}
}
}
var square = Rect(origin: Point(x: 0.0, y: 0.0), size: Size(width: 10.0, height: 10.0))
let initialSquareCenter = square.center
square.center = Point(x: 15.0, y: 15.0)
print("square.origin is now at (\\(square.origin.x), \\(square.origin.y))")
// "square.origin is now at (10.0, 10.0)" ๋ฅผ ์ธ์ํจ
์ ์ฝ๋๋ ์ขํ์ํฌ๊ธฐ๋ฅผ ๊ฐ๋ ์ฌ๊ฐํ์ ํํํ๋ ๊ตฌ์กฐ์ฒด์ ๊ดํ ์ฝ๋์ด๋ค. ์ฌ๊ธฐ์ Rect ๊ตฌ์กฐ์ฒด๋ ์ฌ๊ฐํ์ ์ค์ ์ ํํํ๋ center๋ผ๋ ์ฐ์ฐ ํ๋กํผํฐ๋ฅผ ์ ๊ณตํ๋ค. ์ด ํ๋กํผํฐ๋ ๊ณ์ฐ๋ ํ๋กํผํฐ์ ์ ์๋๋ก ๊ฐ์ ์ง์ ๊ฐ๊ณ ์๋ ๊ฒ์ด ์๋๋ผ ๋ค๋ฅธ ์ขํ์ ํฌ๊ธฐ ํ๋กํผํฐ๋ค์ ์ ์ ํ ์ฐ์ฐํด์ ๊ตฌํ ์ ์๋ค. (get) ๋ set์ผ๋ก ์ฌ๊ฐํ์ ์ค์ ์ ์ง์ ์ค์ ํ ์ ์๋๋ฐ, ์ด ๊ฐ์ ์ค์ ํ ๋ x, y ์ขํ๊ฐ ์ด๋ค ๊ฐ์ ๊ฐ์ ธ์ผํ๋์ง x, y์ ์ ์ ํ ์ขํ๊ฐ์ ๋ฃ์ด์ค๋ค.
โถ ์ฝ๋์ค๋ช
- ๋ค์์ผ๋ก square.center ์ ํตํด square ๋ณ์์ center ํ๋กํผํฐ์ ์ ๊ทผํ๋๋ฐ, ์ด๋ center์ getter์ ํธ์ถํ์ฌ ํ์ฌ ์์ฑ๊ฐ์ ๊ฐ์ ธ์จ๋ค. ๊ธฐ์กด ๊ฐ์ ๋ฐํํ๋ค๊ธฐ ๋ณด๋ค๋, ์ Point๋ฅผ ๊ณ์ฐํ์ฌ ๋ฐํํด์ค๋ค. ์์ฝ๋์์ ๋ณด๋ฉด, getter๋ (5,5)๋ผ๋ ์ค์ฌ์ ์ ๋ฐํํ๋ค.
- ๊ทธ ๋ค์, center ํ๋กํผํฐ์ (15, 15)๋ผ๋ ์๋ก์ด ๊ฐ์ ์ค์ ํ๋ค. ์ด๋ ์ ์ฌ๊ฐํ์ ์ค๋ฅธ์ชฝ ์, ์๋ ๊ทธ๋ฆผ์์๋ ์ค๋ ์ง์ ์ ์ฌ๊ฐํ์ ์์น๋ก ์ด๋์ํจ๋ค. center ํ๋กํผํฐ๋ฅผ ์ค์ ํ๋ฉด center์ setter์ ํธ์ถํ๋๋ฐ ์ด๋ orgin์ด๋ผ๋ ์ ์ฅ ํ๋กํผํฐ์ x์ y๊ฐ์ ์์ ํ์ฌ ์ ์ฌ๊ฐํ์ ์ ์์น๋ก ์ด๋์ํจ๋ค.
- square ๋ผ๋ ์๋ก์ด Rect ๋ณ์๋ฅผ ์์ฑํ๋ค. square๋ณ์๋ (0,0) ์ด๋ผ๋ ์์ ๊ณผ, (10, 10)์ด๋ผ๋ ํญ๊ณผ ๋์ด๋ก ์ด๊ธฐํ๋๋ค. ์๋ ๊ทธ๋ฆผ์ ํ๋์ ์ฌ๊ฐํ์ด ์ด ์ฌ๊ฐํ์ด๋ค.
Shorted Setter Declaration (Setter ์ ์ธ์ ๊ฐ๋ตํ ํํ)
์์ ์ฝ๋์์๋ Setter์ ์ธ์ ์ด๋ฆ์ ์๋์ ๊ฐ์ด set(newCenter)๋ผ๊ณ ๋ช ์ํ์ง๋ง, ๋ง์ฝ ์ด๋ ๊ฒ newCenter๋ผ๊ณ ์ธ์ ์ด๋ฆ์ ์ ํ์ง ์์ผ๋ฉด ์ธ์ ๊ธฐ๋ณธ ์ด๋ฆ์ธ newValue๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
struct AlternativeRect {
var origin = Point()
var size = Size()
var center: Point {
get {
let centerX = origin.x + (size.width / 2)
let centerY = origin.y + (size.height / 2)
return Point(x: centerX, y: centerY)
}
set {
origin.x = newValue.x - (size.width / 2)
origin.y = newValue.y - (size.height / 2)
}
}
}
์ ์ฝ๋์์ set ๋ฉ์๋ ์์์ ์ธ์ ์ด๋ฆ์ ์ง์ ํ์ง ์์๋๋ฐ๋ newValue.x, newValue.y๋ฅผ ์ฌ์ฉํ ์ ์๋ค๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
Shorthand Getter Declaration
์ ์ฒด getter ๋ณธ๋ฌธ์ด ๋จ์ผ ํํ์์ด๋ฉด, getter์ ์์์ ์ผ๋ก ๊ทธ ํํ์์ ๋ฐํํ๋ค.
struct CompactRect {
var origin = Point()
var size = Size()
var center: Point {
get {
Point(x: origin.x + (size.width / 2), y: origin.y + (size.height / 2))
}
set {
origin.x = newValue.x - (size.width / 2)
origin.y = newValue.y - (size.height / 2)
}
}
}
getter์์ return์ ์๋ตํ๋ค. ์ด๋ ํจ์์์ return์ ์๋ตํ๋ ๊ฒ๊ณผ ๋์ผํ ๊ท์น์ ๊ฐ๋๋ค.
Read-Only Computed Properties
getter๋ง ์๊ณ setter๋ฅผ ์ ๊ณตํ์ง ์๋ ์ฐ์ฐ ํ๋กํผํฐ๋ฅผ ์ฝ๊ธฐ์ ์ฉ ํ๋กํผํฐ๋ผ๊ณ ํ๋ค. ์ฆ, ์ฝ๊ธฐ์ ์ฉ ์ฐ์ฐ ํ๋กํผํฐ๋ ๋ฐ๋์ ๋ฐํ๊ฐ์ ์ ๊ณตํ๊ณ ๋ค๋ฅธ๊ฐ์ ์ง์ ํ ์ ์๋ ํ๋กํผํฐ์ด๋ค.
โถ Note
- ์ฝ๊ธฐ์ ์ฉ ์ฐ์ฐ ํ๋กํผํฐ๋ฅผ ํฌํจํ์ฌ ์ฐ์ฐํ๋กํผํฐ๋ฅผ ์ ์ธํ ๋๋ ๋ฐ๋์ let์ด ์๋๋ผ var๋ก ์ ์ธํด์ฃผ์ด์ผ ํ๋ค. ๋ณดํต ์ฝ๊ธฐ ์ ์ฉ์ด๋ผ ํจ์ ํ๋ฒ ๊ฐ์ด ์ ํด์ง๋ฉด ๋ณํ์ง ์๊ธฐ ๋๋ฌธ์ let์ผ๋ก ์ ์ธํ๋ ๊ฒ์ด ๋ง์ผ๋, ์ฐ์ฐ ํ๋กํผํฐ๋ ์ฝ๊ธฐ์ ์ฉ์ด๋ผ ํ๋๋ผ๋ ๊ณ์ฐ๊ฐ์ ๋ฐ๋ผ ๊ฐ์ด ๋ณํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๋์ ๊ผญ var๋ก ๋ณ์๋ฅผ ์ ์ธํด์ผํ๋ค!
struct Cuboid {
var width = 0.0, height = 0.0, depth = 0.0
var volume: Double {
return width * height * depth
}
}
let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)
print("the volume of fourByFiveByTwo is \\(fourByFiveByTwo.volume)")
// "the volume of fourByFiveByTwo is 40.0" ๋ฅผ ์ธ์ํจ
โถ ์ฝ๋์ค๋ช
- width, height, depth ์์ฑ์ผ๋ก 3์ฐจ์ ์ง์ฌ๊ฐํ ์์ฑ์ ๋ํ๋ด๋ Cuboid ๊ตฌ์กฐ์ฒด
- ์ด ๊ตฌ์กฐ์ฒด๋ ์ง์ก๋ฉด์ฒด์ ํ์ฌ ๋ถํผ๋ฅผ ๊ณ์ฐํ์ฌ ๋ฐํํ๋ volume์ด๋ผ๋ ์ฝ๊ธฐ ์ ์ฉ ์ฐ์ฐ ํ๋กํผํฐ๋ฅผ ๊ฐ์ง
- ํ์ฌ ๊ณ์ฐํ ๋ถํผ๋ฅผ ์ธ๋ถ ์ฌ์ฉ์๊ฐ ๋ฐ๊ฒฌํ ์ ์๋๋ก Cuboid ๊ฐ ์ฝ๊ธฐ์ ์ฉ ํ๋กํผํฐ๋ฅผ ์ ๊ณตํจ
Property Observer
ํ๋กํผํฐ ์ต์ ๋ฒ๋ ์ ๊ฐ์ด ์ค์ (set)๋ ๋๋ง๋ค ํด๋น ์ด๋ฒคํธ๋ฅผ ๊ฐ์งํ ์ ์๊ฒํ๋ ๊ธฐ๋ฅ์ด๋ค.
- ํ๋กํผํฐ ์ต์ ๋ฒ๋ ์ ๊ฐ์ด ์ด์ ๊ฐ๊ณผ ๊ฐ๋๋ผ๋ ํญ์ ํธ์ถ๋๋ค.
- lazy ์ ์ฅ ํ๋กํผํฐ์์๋ ์ฌ์ฉํ ์ ์๋ค
- sub class์ ํ๋กํผํฐ์ ์ต์ ๋ฒ๋ฅผ ์ ์ํ๋ ๊ฒ์ ๊ฐ๋ฅํ๋ค
- ์ฐ์ฐ ํ๋กํผํฐ์์๋!! setter ์์ ๊ฐ์ ๋ณํ๋ฅผ ๊ฐ์งํ ์ ์๊ธฐ ๋๋ฌธ์ ๋ฐ๋ก ์ต์ ๋ฒ๋ฅผ ์ ์ํ ํ์๊ฐ ์๋ค.
โถ๏ธ willSet
๊ฐ์ด ์ ์ฅ๋๊ธฐ ๋ฐ๋ก ์ง์ ์ ํธ์ถ ๋จ
willSet์์๋ ์ ๊ฐ์ ํ๋ผ๋ฏธํฐ ๋ช ์ ์ง์ ํ ์ ์๋๋ฐ, ์ง์ ํ์ง ์์ผ๋ฉด ๊ธฐ๋ณธ๊ฐ์ผ๋ก newValue๋ฅผ ์ฌ์ฉํ๋ค.
โถ๏ธ didSet
์ ๊ฐ์ด ์ ์ฅ๋๊ณ ๋ ์งํ์ ํธ์ถ ๋จ
didSet์์๋ ๋ฐ๋๊ธฐ ์ ์ ๊ฐ์ ํ๋ผ๋ฏธํฐ๋ช ์ ์ง์ ํ ์ ์๋๋ฐ ์ง์ ํ์ง ์์ผ๋ฉด oldValue๋ฅผ ์ฌ์ฉํ๋ค.
โถ Note
- ์๋ธํด๋์ค์์ ํน์ ํ๋ผ๋ฏธํฐ์ ๊ฐ์ ์ค์ ํ์ ๋, ์ํผํด๋์ค์ initializer๊ฐ ํธ์ถ ๋ ํ, willSet, didSet ํ๋กํผํฐ ์ต์ ๋ฒ๊ฐ ์คํ๋๋ค. ์ํผํด๋์ค์์ ํ๋กํผํฐ๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒ๋ ๋ง์ฐฌ๊ฐ์ง๋ก ์ํผํด๋์ค์ initializer๊ฐ ํธ์ถ๋ ํ ์ต์ ๋ฒ๊ฐ ์คํ๋๋ค.
class StepCounter {
var totalSteps: Int = 0 {
willSet(newTotalSteps) {
print("About to set totalSteps to \\(newTotalSteps)")
}
didSet {
if totalSteps > oldValue {
print("Added \\(totalSteps - oldValue) steps")
}
}
}
}
let stepCounter=StepCounter()
stepCounter.totalSteps= 200
// totalSteps ๋ฅผ 200 ์ผ๋ก ์ค์ ํ๋ ค๊ณ ํจ
//200 ๊ฑธ์์ ์ถ๊ฐํจ
stepCounter.totalSteps= 360
// totalSteps ๋ฅผ 360 ์ผ๋ก ์ค์ ํ๋ ค๊ณ ํจ
// 160 ๊ฑธ์์ ์ถ๊ฐํจ
stepCounter.totalSteps= 896
// totalSteps ๋ฅผ 896 ์ผ๋ก ์ค์ ํ๋ ค๊ณ ํจ
// 536 ๊ฑธ์์ ์ถ๊ฐํจ
ํ๋กํผํฐ ์ต์ ๋ฒ willSet๊ณผ didSet์ ์ฌ์ฉํ๋ค. willSet์์๋ ์๋ก์ด ๊ฐ์ ํ๋ผ๋ฏธํฐ๋ช ์ผ๋ก newTotalSteps๋ฅผ ์ง์ ํด์ ์ฌ์ฉํ๊ณ , didSet์์๋ ๋ณํ๊ธฐ ์ ์ ๊ฐ์ ์๋ฏธํ๋ ํ๋ผ๋ฏธํฐ๋ช ์ ์ง์ ํ์ง ์๊ณ oldValue๋ผ๋ ๊ธฐ๋ณธ ํ๋ผ๋ฏธํฐ๋ช ์ ์ด์ฉํ๋ค.
โถ ์ฝ๋ ์ค๋ช
- willSet์ ์๋ก ๋ค๊ฐ์ฌ ๊ฐ์ผ๋ก, newTotalSteps ๋ผ๋ ์ฌ์ฉ์ ์ ์ ๋งค๊ฐ๋ณ์ ์ด๋ฆ์ ์ฌ์ฉํ๊ณ ์ด ์์ ์์๋ ์ค์ ํ๋ ค๋ ๊ฐ์ ๋จ์ํ ์ธ์ํด์ค๋ค.
- totalStep๊ฐ์ ๊ฐฑ์ ํ ํ, didSet์ด ํธ์ถ๋จ. totalSteps ๊ฐ๊ณผ ์์ ๊ฐ์ ๋น๊ตํด์ ์ด ๊ฑธ์ ์๊ฐ ์ฆ๊ฐํ์ผ๋ฉด, ์ ๊ฑธ์ ์๊ฐ ์ผ๋ง์ธ์ง ํ์ํ๊ณ ์ ๋ฉ์์ง๋ฅผ ์ธ์ํจ.
- didSet์ ์์ ๊ฐ์ ์ฌ์ฉ์ ์ ์ ๋งค๊ฐ๋ณ์ ์ด๋ฆ์ ์ ๊ณตํ์ง ์๊ณ oldValue๋ผ๋ ์ด๋ฆ์ ์ฌ์ฉํจ.
Property Wrappers
Property Wrapper ๋ ํ๋กํผํฐ๊ฐ ์ ์ฅ๋๋ ๋ฐฉ์์ ๊ด๋ฆฌํ๋ ์ฝ๋์ ํ๋กํผํฐ๋ฅผ ์ ์ํ๋ ์ฝ๋ ์ฌ์ด์ ๋ถ๋ฆฌ ๊ณ์ธต์ ์ถ๊ฐํ๋ ๊ฒ์ด๋ค.
์ธ์ ์ฌ์ฉํ๋?
- Thread-safeํ ํ๋กํผํฐ ๋๋ ๊ฐ์ DB์ ์ ์ฅํ๋ ํ๋กํผํฐ๊ฐ ์ฌ๋ฌ ๊ฐ ํ์ํ ๋
- ์ง๊ธ๊น์ง๋ ์ด๋ด ๋ thread-safe ์ฒ๋ฆฌ, DB ์ปค๋ฅ์ ์ฒ๋ฆฌ ๋ฑ์ ์ํ ์ฝ๋๋ฅผ ๊ฐ๊ฐ์ ํ๋กํผํฐ์ ๋ชจ๋ ์์ฑํด์ฃผ์ด์ผ ํ์.
- Property wrapper ๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด ์ด๋ฐ ์ฝ๋ (๊ฐ ์ ์ฅ์ ๊ด๋ฆฌํ๋ ์ฝ๋)๋ค์ Property wrapper๋ฅผ ์ ์ํ๋ ๋ถ๋ถ์์ ์ต์ด ํ ๋ฒ๋ง ์์ฑํ๋ฉด ๋จ.
- ๊ทธ ํ ํ์ํ ํ๋กํผํฐ๋ค์์ ์ด wrapper๋ฅผ ๊ฐ์ ธ๋ค ์ ์ฉํจ์ผ๋ก์จ ํ๋์ ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉํ ์ ์๊ฒ ๋จ.
Property wrapper ์ฌ์ฉ์ ์ํด์๋ ๊ตฌ์กฐ์ฒด, ํด๋์ค, ์ด๊ฑฐํ์์ wrapperValue๋ผ๊ณ ํ๋ ํ๋กํผํฐ๋ฅผ ์ ์ธํด์ผํ๋ค. ์์๋ฅผ ๋ณด์.
@propertyWrapper
struct TwelveOrLess {
private var number: Int
init() { self.number = 0 }
var wrappedValue: Int {
get { return number }
set { number = min(newValue, 12) }
}
}
์ ์ฝ๋์์๋ TwelveOrLess ๊ตฌ์กฐ์ฒด๋ wrappedValue์ ํญ์ 12๋ณด๋ค ์์ ๊ฐ์ด ์ ์ฅ๋๊ฒ ๋ง๋๋ ์ฝ๋์ด๋ค. ๋ง์ฝ 12๋ณด๋ค ํฐ ์๋ผ๋ฉด, 12๋ฅผ ์ ์ฅํ๊ฒ ๋ง๋ ๋ค. ์์์ ์ ์ธํ TwelveOrLess ๊ตฌ์กฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ๋ค๋ฅธ ๊ตฌ์กฐ์ฒด๋ฅผ ๋ง๋ค๋ฉด ์๋์ ๊ฐ๋ค.
struct SmallRectangle {
@TwelveOrLess var height: Int
@TwelveOrLess var width: Int
}
var rectangle = SmallRectangle()
print(rectangle.height)
// "0" ์ ์ธ์ํจ
rectangle.height = 10
print(rectangle.height)
// "10" ์ ์ธ์ํจ
rectangle.height = 24
print(rectangle.height)
// "12" ๋ฅผ ์ธ์ํจ
์ ์ฝ๋์ฒ๋ผ ๋ค๋ฅธ ๊ตฌ์กฐ์ฒด์ ํ๋กํผํฐ์ Property wrapper๋ฅผ ์ฌ๋ฌ๋ฒ ์ฌ์ฌ์ฉํ์ฌ ์ฌ์ฉํ ์ ์๋ค. Property wrapper๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ Property Wrapper์ ์ด๋ฆ์ @๋ฅผ ํจ๊ป ์จ์ฃผ๋ฉด ๋๋ค. SmallRectangle์ height, width ํ๋กํผํฐ๋ Property wrapper ๊ฐ ์ ์ฉ๋ ์ํ์ด๊ธฐ ๋๋ฌธ์ 12์ด์์ ๊ฐ์ ๊ฐ์ง ์ ์๊ฒ ๋๋ค.
struct SmallRectangle {
private var _height = TwelveOrLess()
private var _width = TwelveOrLess()
var height: Int {
get { return _height.wrappedValue }
set { _height.wrappedValue = newValue }
}
var width: Int {
get { return _width.wrappedValue }
set { _width.wrappedValue = newValue }
}
}
์์ Property Wrapper๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด property wrapper๋ก ์ ์ธ๋ ํ๋กํผํฐ์ ๊ฐ์ ์ ์ฅํด์ผํ๊ธฐ ๋๋ฌธ์ getter, setter๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋๋ค.
Setting Initial Values for Wrapped Properties
์์ ์์ฑ๋ ์ฝ๋๋ property wrapper์์ ์ด๊ธฐ๊ฐ์ ์ ์ํ ์ ์์๋ค. ๊ทธ๋ฌ๊ธฐ ๋๋ฌธ์ ๋ํ๋ ํ๋กํผํฐ๋ ๋ค๋ฅธ ์ด๊ธฐ๊ฐ์ ์ง์ ํ ์ ์์๋๋ฐ, ์ด๋ฌํ ์ ์ ๋ณด์ํ๊ธฐ ์ํด์๋ property wrapper์ ์์ฑ์๋ฅผ ์ถ๊ฐํด์ฃผ๋ฉด ๋๋ค.
@propertyWrapper
struct SmallNumber {
private var maximum: Int
private var number: Int
var wrappedValue: Int {
get { return number }
set { number = min(newValue, maximum) }
}
init() {
maximum = 12
number = 0
}
init(wrappedValue: Int) {
maximum = 12
number = min(wrappedValue, maximum)
}
init(wrappedValue: Int, maximum: Int) {
self.maximum = maximum
number = min(wrappedValue, maximum)
}
}
์์ ์ฝ๋์์ property wrapper๋ก ์ฌ์ฉ๋ ๊ตฌ์กฐ์ฒด์๋ 3๊ฐ์ ์์ฑ์๊ฐ ์๋ค. ์ด๋ ๊ฒ ์์ฑ์๊ฐ ์ถ๊ฐ๋ property wrapper๋ฅผ ์ ์ฉํ ์๋ฅผ ์ดํด๋ณด์.
struct ZeroRectangle {
@SmallNumber var height: Int
@SmallNumber var width: Int
}
var zeroRectangle = ZeroRectangle()
print(zeroRectangle.height, zeroRectangle.width)
// "0 0" ๋ฅผ ์ธ์ํจ
์ด์ ์์ ์๋ฅผ ํตํด์ ์ด๊ธฐ ๊ฐ์ ์ ์ธํ ์ ์๊ฒ ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
struct UnitRectangle {
@SmallNumber var height: Int = 1
@SmallNumber var width: Int = 1
}
var unitRectangle = UnitRectangle()
print(unitRectangle.height, unitRectangle.width)
// "1 1" ๋ฅผ ์ธ์ํจ
์์ ๊ฐ์ด height, width์ 1์ ํ ๋นํ๊ฒ ๋๋ฉด ์ด๋ property wrapper์ init ์์ฑ์๋ฅผ ํธ์ถํ๊ฒ ๋๋ค.
struct NarrowRectangle {
@SmallNumber(wrappedValue: 2, maximum: 5) var height: Int
@SmallNumber(wrappedValue: 3, maximum: 4) var width: Int
}
var narrowRectangle = NarrowRectangle()
print(narrowRectangle.height, narrowRectangle.width)
// "2 3" ๋ฅผ ์ธ์ํจ
narrowRectangle.height = 100
narrowRectangle.width = 100
print(narrowRectangle.height, narrowRectangle.width)
// "5 4" ๋ฅผ ์ธ์ํจ
property wrapper์ ์ธ์๋ฅผ ํฌํจํ ๋ ํ ๋น์ ์ฌ์ฉํ์ฌ ์ด๊ธฐ๊ฐ์ ์ง์ ํ ์ ์๋ค. heightํ๋กํผํฐ๋ฅผ ๊ฐ์ธ๋ SmallNumber ์ธ์คํด์ค๋ SmallNumber(wrappedValue:1)์ ํธ์ถํ์ฌ ์ด๊ธฐํ ํ๊ณ , width ํ๋กํผํฐ๋ฅผ ๊ฐ์ธ๋ SmallNumber ์ธ์คํด์ค๋ SmallNumber(wrappedValue:2, maximum:9)๋ฅผ ํธ์ถํ์ฌ ์ด๊ธฐํ๋๋ค.
Global and Local Variables
์์์ ์๊ฐํ ๊ณ์ฐ๋ ํ๋กํผํฐ์ ํ๋กํผํฐ ์ต์ ๋ฒ ๊ธฐ๋ฅ์ ์ ์ญ๋ณ์์ ์ง์ญ๋ณ์ ๋ชจ๋์์ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค. ์ ์ญ๋ณ์(global)๋ ์ด๋ค ํจ์๋, ๋ฉ์๋, ํด๋ก์ ๋ฐ ํ์ ๋ฐ์์ ์ ์ํ ๋ณ์์ด๋ค. ์ง์ญ๋ณ์(local)์ ํจ์๋, ๋ฉ์๋ ๋ฐ ํด๋ก์ ์์์ ์ ์ํ ๋ณ์์ด๋ค.
์์ ๋ฐฐ์ด ๋ชจ๋ ์ ์ญ๋ณ์์ ์ง์ญ๋ณ์๋ Stored Variable (์ ์ฅ๋ ๋ณ์) ์๋ค. ์ด๋ ์ ์ฅ ํ๋กํผํฐ์ ๋น์ทํ๊ฒ ๊ฐ์๊ฒ ์ ์ฅ๊ณต๊ฐ์ ์ฃผ๊ณ ํด๋น ๊ฐ์ ์ค์ ํ๊ณ , ๊ฒ์ํ ์ ์๊ฒ ํด์ค๋ค.
๋ฌผ๋ก , ์ ์ญ ๋ฒ์์ ์ง์ญ ๋ฒ์์์ Computed Variable๋ฅผ ์ ์ํ๊ณ ๋ณ์์ ๋ํ ์ต์ ๋ฒ๋ฅผ ์ ์ํ ์๋ ์๋ค. Computed Variable์ ๊ฐ์ ์ ์ฅํ์ง ์๊ณ ๊ณ์ฐ ํ๋กํผํฐ์ ๊ฐ์ ๋ฐฉ์์ผ๋ก ์ฐ์ธ๋ค.
์ ์ญ๋ณ์, ์์๋ lazy ์ ์ฅ ํ๋กํผํฐ์ ๋์ผํ ๋ฐฉ๋ฒ์ผ๋ก ์ฒ๋ฆฌ๋๋ค. ํ์ง๋ง ์ ์ญ๋ณ์ ๋ฐ ์์์ lazyํค์๋๋ฅผ ํ์ํ ํ์๋ ์๋ค.
์ด์ ๋ฐ๋๋ก ์ง์ญ๋ณ์, ์์์๋ ์ ๋๋ก lazy๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
Type Properties
๊ฐ๊ฐ์ ์ธ์คํด์ค๊ฐ ์๋ ํ์ ์์ฒด์ ์ํ๊ฒ ๋๋ ํ๋กํผํฐ๋ฅผ ํ์ ํ๋กํผํฐ๋ผ๊ณ ํ๋ค.
์ด์ ๊น์ง ์์๋ณธ ํ๋กํผํฐ ๊ฐ๋ ์ ๋ชจ๋ ํ์ ์ ์ ์ํ๊ณ ๊ทธ ํ์ ์ ์ธ์คํด์ค๊ฐ ์์ฑ๋์์๋ ์ฌ์ฉ๋ ์ ์๋ ์ธ์คํด์ค ํ๋กํผํฐ์ด๋ค. ์ธ์คํด์ค ํ๋กํผํฐ๋ ์ธ์คํด์ค๋ฅผ ์๋ก ์์ฑํ ๋ ๋ง๋ค ์ด๊น๊ฐ์ ํด๋นํ๋ ๊ฐ์ด ํ๋กํผํฐ์ ๊ฐ์ด ๋๊ณ , ๊ฐ ์ธ์คํด์ค๋ง๋ค ๋ค๋ฅธ ๊ฐ์ ์ง๋ ์ ์๋ค.
ํ์ ํ๋กํผํฐ๋ ํ์ ์์ฒด์ ์ํฅ์ ๋ฏธ์น๋ ํ๋กํผํฐ์ด๊ณ ์ธ์คํด์ค์ ์์ฑ ์ฌ๋ถ์ ์๊ด์์ด ํ์ ํ๋กํผํฐ์ ๊ฐ์ ํ๋์ด๋ค. ์ด ํ์ ํ๋กํผํฐ๋ ํน์ ํ์ ์ ๋ชจ๋ ์ธ์คํด์ค์ ๊ณตํต์ผ๋ก ์ฌ์ฉ๋๋ ๊ฐ์ ์ ์ํ ๋ ์ ์ฉํ๋ค.
Type Property Syntax
ํ์ ์์ฑ์ static ํค์๋๋ก ์ ์ํ๋ค. ํด๋์ค์์๋ static๊ณผ class ์ด๋ ๊ฒ 2๊ฐ์ง ํํ๋ก ํ์ ํ๋กํผํฐ๋ฅผ ์ ์ธํ ์ ์๋๋ฐ ๋๊ฐ์ง ๊ฒฝ์ฐ์ ์ฐจ์ด๋ ์๋ธํด๋์ค์์ overriding ๊ฐ๋ฅ ์ฌ๋ถ์ด๋ค. class ๋ก ์ ์ธ๋ ํ๋กํผํฐ๋ ์๋ธํด๋์ค์์ override ๊ฐ๋ฅํ๋ค.
struct SomeStructure {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 1
}
}
enum SomeEnumeration {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 6
}
}
class SomeClass {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 27
}
class var overrideableComputedTypeProperty: Int {
return 107
}
}
โถ Note
- ์์ ์ฐ์ฐ ํ์ ํ๋กํผํฐ ์์๋ ์ฝ๊ธฐ์ ์ฉ์ด์ง๋ง, ๊ฐ์ ๋ฌธ๋ฒ์ผ๋ก ์ฐ์ฐ๋ ์ธ์คํด์ค์ ํ์ ํ๋กํผํฐ์์๋ ์ฝ๊ณ ์ธ ์ ์๋ ํ๋กํผํฐ๋ก ์ฌ์ฉ ๊ฐ๋ฅํ๋ค. (์๋์์)
class Aclass {
// ์ ์ฅ ํ์
ํ๋กํผํฐ
static var typeProperty: Int = 0
var instanceProperty: Int = 0 {
didSet {
Aclass.typeProperty = instanceProperty + 100
}
}
// ์ฐ์ฐ ํ์
ํ๋กํผํฐ
static var typeComputedProperty: Int {
get {
return typeProperty
}
set {
typeProperty = newValue
}
}
}
- ์ถ๊ฐ์ค๋ช
- ์ ์ฅ&์ฐ์ฐ ํ๋กํผํฐ ์์ static ์ด๋ ํค์๋๋ฅผ ๋ถ์ด๋ฉด ์ ์ฅ(์ฐ์ฐ)ํ์ ํ๋กํผํฐ๊ฐ ๋จ
Querying and Setting Type Properties
ํ์ ํ๋กํผํฐ๋ ๊ทธ๋ฅ ์ธ์คํด์ค ์์ฑ๊ณผ ๊ฐ์ด ์ ๊ตฌ๋ฌธ์ผ๋ก ์กฐํํ๊ณ ์ค์ ํ๋ค.
print(SomeStructure.storedTypeProperty)
// "Some value." ๋ฅผ ์ธ์ํจ
SomeStructure.storedTypeProperty = "Another value."
print(SomeStructure.storedTypeProperty)
// "Another value." ๋ฅผ ์ธ์ํจ
print(SomeEnumeration.computedTypeProperty)
// "6" ์ ์ธ์ํจ
print(SomeClass.computedTypeProperty)
// "27" ์ ์ธ์ํจ
์๋ ์ค๋์ค ์ฑ๋์ ๋ณผ๋ฅจ์ ์กฐ์ ํ๊ณ ๊ด๋ฆฌํ๋ ๊ตฌ์กฐ์ฒด ์์ ๋ฅผ ์ดํด๋ณด์.
struct AudioChannel {
static let thresholdLevel = 10
static var maxInputLevelForAllChannels = 0
var currentLevel: Int = 0 {
didSet {
if currentLevel > AudioChannel.thresholdLevel {
// ์๋ก์ด ์๋์ ์ํ์ ์๊ณ์น๊น์ง๋ก ์ ํํจ
currentLevel = AudioChannel.thresholdLevel
}
if currentLevel > AudioChannel.maxInputLevelForAllChannels {
// ์ด๋ฅผ ์๋ก์ด ์ ์ฒด ์ต๋ ์
๋ ฅ๋์ผ๋ก ์ ์ฅํจ
AudioChannel.maxInputLevelForAllChannels = currentLevel
}
}
}
}
์ ์ฝ๋๋ ํ์ฌ ์ค๋์ค ์ต๋ ๋ณผ๋ฅจ ํฌ๊ธฐ๋ ํ์ ํ๋กํผํฐ maxInputLevelForAllChannels๋ก ๊ด๋ฆฌํ๊ณ , ๊ทธ ๊ฐ์ thresholdLevel๋ก ์์๋ก ์ ์๋ผ ์์ด์ currentLevel์ ์ค์ ํ ๋ ๋ง๋ค (didSet) ์ฑ๋๋ณ ๋ณผ๋ฅจ์ด ์ต๋ ๊ทธ ๊ฐ์ ๋์ง ๋ชปํ๋๋ก ์กฐ์ ํด์ฃผ๋ ๊ตฌ์กฐ์ฒด์ด๋ค.
์ด๋ ๊ฒ ๋ง๋ ์ค๋์ค ์ฒด๋ ๊ตฌ์กฐ์ฒด๋ฅผ ์ด์ฉํด ์ข์ฐ ๋๊ฐ์ ์ค๋์ค ์ฑํธ์ ์์ฑํ ์ ์๋ค.
var leftChannel = AudioChannel()
var rightChannel = AudioChannel()
์ด์ leftChannel์ 7์ ํ ๋นํด๋ณด์.
leftChannel.currentLevel = 7
print(leftChannel.currentLevel)
// Prints "7"
print(AudioChannel.maxInputLevelForAllChannels)
// Prints "7"
๊ทธ๋ผ ์ฑ๋์์ ์ต๋๊ฐ์ผ๋ก ์ค์ ํ ๊ฐ์ ๋์ด๊ฐ๋ 11์ ํ ๋นํด๋ณด์.
rightChannel.currentLevel = 11
print(rightChannel.currentLevel)
// Prints "10"
print(AudioChannel.maxInputLevelForAllChannels)
// Prints "10"
์ต๋๊ฐ 10์ด ๋์ด๊ฐ๋ ๊ฐ์ ํ ๋นํ์, 11์ ์ ๋ ฅํ์ง๋ง 10์ผ๋ก ์ค์ ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.