swift ์ธ์ด์ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ๋ฌธ๋ฒ์ธ property์ ๋ํด ์ ๋ฆฌํด๋ณด๋ ค๊ณ ํฉ๋๋ค.
์ค์ํํธ์ property๋ ์๋์ ๊ฐ์ด 3๊ฐ์ง๋ก ๊ตฌ๋ถํ ์ ์์ต๋๋ค.
- stored Property (์ ์ฅ ํ๋กํผํฐ)
- computed property (์ฐ์ฐ ํ๋กํผํฐ)
- type property (ํ์ ํ๋กํผํฐ)
๊ธฐ๋ณธ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ์ฌ ์ ๋ฆฌํ์์ต๋๋ค.
https://docs.swift.org/swift-book/LanguageGuide/Properties.html
stored Property
์์(constant)์ ๋ณ์(variable)๊ฐ์ ์ธ์คํด์ค์ ์ผ๋ถ๋ก ์ ์ฅํฉ๋๋ค.
ํด๋์ค์ ๊ตฌ์กฐ์ฒด์์๋ง ์ฌ์ฉ
computed Property
์ฐ์ฐ์ ์ํํ ๊ฐ์ ๋ฐํํ์ฌ ์ธ์คํด์ค์ ์ผ๋ถ๋ก ์ ์ฅ๋ฉ๋๋ค.
ํด๋์ค, ๊ตฌ์กฐ์ฒด, ์ด๊ฑฐํ์์ ์ฌ์ฉ
type property
property ์์ฒด๋ฅผ ํ์ ๊ณผ ์ฐ๊ฒฐํฉ๋๋ค..? ๋ฌด์จ๋ง์ผ๊น๋์ ์๋์์ ์ข๋ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
property observers
์ฌ์ฉ์์ ์ก์ ์ ์๋ตํ๊ธฐ ์ํด, property ๊ฐ์ ๋ณ๊ฒฝ์ฌํญ์ ๊ฐ์(observing) ํฉ๋๋ค.
์์ ํ๋ ํ๋ ์์ธํ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
stored Property
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
// the range represents integer values 0, 1, and 2
rangeOfThreeItems.firstValue = 6
// the range now represents integer values 6, 7, and 8
์ฐ๋ฆฌ๊ฐ ํํ ๋ณด๋ var, let ์ผ๋ก ์ ์ธ๋ firstValue, length๊ฐ ๋ฐ๋ก stored property์ธ๋ฐ์.FixedLengthRange ๊ฐ์ฒด๋ฅผ ํ๋ ์์ฑํ ๋ค firstValue์ ๊ฐ์ ๋ฃ์ด์คฌ์ฃ ? ํ์ ์ด ๊ฐ์ ์ ๊ทผํ๊ฒ ๋๋ค๋ฉด ์ ์ฅ๋ 6์ ์ถ๋ ฅํด ์ค๊ฒ์ ๋๋ค.
๋ํ rangeOfThreeItems๊ฐ var ์ฆ ๋ณ์๋ก ์ ์ธ๋์ด ์๊ธฐ ๋๋ฌธ์ fistValue์ ๊ฐ์ ์ฌํ ๋นํด์ค ์ ์์์ต๋๋ค.
์ด๋ฅผ let์ผ๋ก ์ ์ธํ๋ค๋ฉด?
let rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
// this will report an error, even though firstValue is a variable property
rangeOfFourItems.firstValue = 6
firstValue๊ฐ ๋ถ๋ช var๋ก ์ ์ธ๋์ด ์์์๋ error๊ฐ ๋๊ฒ ๋๋๋ฐ์. ์ด๊ฒ์ struct๊ฐ value type ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค.
๊ทธ๋ ๋ค๋ฉด reference type์ธ class๋ก ๋ฐ๊พผ๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น์?
class FixedLengthRange {
var firstValue: Int
let length: Int
init(firstValue: Int, length: Int) {
self.firstValue = firstValue
self.length = length
}
}
let rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
rangeOfThreeItems.firstValue = 6
๊ฐ์ฒด๊ฐ let์ผ๋ก ์ ์ธ๋์์์๋ ๋ถ๊ตฌํ๊ณ firstValue๋ class์ ์ ์ธ๋ firstValue ๊ฐ์ ์ฐธ์กฐํ๊ธฐ ๋๋ฌธ์ firstValue์ ์ ๊ทผ์ด ๊ฐ๋ฅํด์ง๋๋ค.
Lazy Stored Properties
๊ฐ์ด ์ฌ์ฉ๋๊ธฐ ์ ๊น์ง ๊ณ์ฐ๋์ด์ง์ง ์๋ property์ ๋๋ค. lazy๋ฅผ ์์ ๋ถ์ฌ์ฃผ๋ฉด ๋ฉ๋๋ค.
* ์ฃผ์ : lazy ํ๋กํผํฐ๋ var๋ก ์ ์ธํด์ผ ํจ ์?
๊ฐ์ฒด ์ด๊ธฐํ๊ฐ ์๋ฃ๋๊ธฐ ์ ๊น์ง ์ด๊ธฐ ๊ฐ์ด ์ค์ ๋์ง ์์ ์๋ ์๊ธฐ ๋๋ฌธ์ด์ฃ .
lazy property๋ property์ ์ด๊ธฐ ๊ฐ์ด ์ธ์คํด์ค ์ด๊ธฐํ๊ฐ ์๋ฃ ๋ ๋๊น์ง ๊ฐ์ ์ ์์๋ ์ธ๋ถ ์์ธ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋ ๊ฒฝ์ฐ์ ์ ์ฉํฉ๋๋ค. ๋ํ property์ ์ด๊ธฐ ๊ฐ์ ๋ณต์กํ๊ฑฐ๋ ๊ณ์ฐ ๋น์ฉ์ด ๋ง์ด ๋๋ ์ค์ ์ด ํ์ํ ๋ or ์ํํ๋ฉด ์๋๋ ๊ฒฝ์ฐ์๋ ์ ์ฉํฉ๋๋ค.
class DataImporter {
/*
DataImporter is a class to import data from an external file.
The class is assumed to take a nontrivial amount of time to initialize.
*/
var filename = "data.txt"
// the DataImporter class would provide data importing functionality here
}
class DataManager {
lazy var importer = DataImporter()
var data = [String]()
// the DataManager class would provide data management functionality here
}
let manager = DataManager()
manager.data.append("Some data")
manager.data.append("Some more data")
// the DataImporter instance for the importer property hasn't yet been created
์ .. ๋ฌด์จ ๋ง์ธ์ง ๋ณต์กํ๋ค.
DataManger์ importer๋ data๋ผ๋ property๋ฅผ ๋น๊ตํด ์ดํด๋ณด์
data property๋ manager ๊ฐ์ฒด ์์ฑ๊ณผ ํจ๊ป ์์ฑ๋์ด ์ธ๋ถ์์ ์ฌ์ฉ๋์๋ค. ํ์ง๋ง importer ๋ ์ฌ์ฉ๋์ง ์์์ผ๋ ๊ฐ์ฒด ์์ฑ์ด ๋์๋๋ผ๊ณ ์ฌ์ฉ๋๊ธฐ ์ ๊น์ง(append์ฒ๋ผ) ์์ฑ๋์ง ์๋๋ค.
๊ทธ๋ฌ๋ฉด ์ธ์ ์์ฑ์ด ๋๋๋ .. dataImporter ํด๋์ค์ property์ธ filename์ด ์ฌ์ฉ๋์ด์ผ importer์ด๋ผ๋ lazy store property๊ฐ ์์ฑ๋๋ค. ๊ทธ๋ฌ๋ dataImporterํด๋์ค์ ์์กด์ ์ด๊ณ ๊ณ์ฐ ๋น์ฉ์ ์ฒ์๋ถํฐ ์ํํ๋๊ฒ์ด ์๋ ํ์ํ ๋ ์ํํ๋ ๊ฒ์ด๋ฏ๋ก ์ค์ผ ์ ์๋ค.
calculated Property
์ค์ ๊ฐ์ ์ ์ฅํ๊ณ ์๋ ๊ฒ์ด ์๋๋ผ getter์ 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)" ์ถ๋ ฅ
์ฌ๊ธฐ์ calculated property๋ center์ด๋ค.
์ด ํ๋กํผํฐ๋ ๊ณ์ฐ๋ ํ๋กํผํฐ์ ์ ์๋๋ก ๊ฐ์ ์ง์ ๊ฐ๊ณ ์๋ ๊ฒ์ด ์๋๋ผ ๋ค๋ฅธ ์ขํ์ ํฌ๊ธฐ ํ๋กํผํฐ๋ค์ ์ ์ ํ ์ฐ์ฐํด์ ๊ตฌํ ์ ์๋ค.
Setter์ ์ธ์ ์ด๋ฆ์ ์๋์ ๊ฐ์ด set(newCenter)๋ผ๊ณ ๋ช ์ํ์ง๋ง ๋ง์ฝ ์ด๋ ๊ฒ (newCenter)๋ผ๊ณ ์ธ์ ์ด๋ฆ์ ์ง์ ํ์ง ์์ผ๋ฉด ์ธ์ ๊ธฐ๋ณธ ์ด๋ฆ์ธ newValue์ผ๋ก ์ฌ์ฉํ๋ค.
Read-Only Computed Properties
getter๋ง ์๊ณ setter๋ ์๋ ํ๋กํผํฐ๋ก ์ฆ ์ฝ์ ์๋ง ์์ง ๊ฐ์ ๋ณํํ๊ณ ๋ค๋ฅธ ๊ฐ์ผ๋ก ์ฌํ ๋นํ๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅํ๋ค
Property Observers
์ ๊ฐ์ด ์ค์ ๋ ๋๋ง๋ค ์ด๋ฅผ ๊ฐ์งํ ์ ์๋ ์ต์ ๋ฒ๋ฅผ ์ ๊ณตํ๋๋ฐ ๋ค์๊ณผ ๊ฐ์ ํน์ง์ ์ง๋๋ค.
1. ํ๋กํผํฐ ์ต์ ๋ฒ๋ ์ ๊ฐ์ด ์ด์ ๊ฐ๊ณผ ๊ฐ๋๋ผ๋ ํญ์ ํธ์ถ๋๋ค.
2. lazy stored properties์์ ์ฌ์ฉ ํ ์ ์๋ค.
3. ์๋ธ ํด๋์ค์ ํ๋กํผํฐ ์ต์ ๋ฒ๋ฅผ ์ ์ํ๋ ๊ฒ๋ ๊ฐ๋ฅํ๋ค.
4. ๊ณ์ฐ๋ ํ๋กํผํฐ๋ setter์์ ๊ฐ์ ๋ณํ๋ฅผ ๊ฐ์งํ๋ฏ๋ก ๋ฐ๋ก ์ต์ ๋ฒ๋ฅผ ์ ์ํ์ง ์๋๋ค.
ํ๋กํผํฐ ์ต์ ๋ฒ์๋ ์๋์ ๊ฐ์ ๋ ์ต์ ๋ฒ๊ฐ ์๋ค!
- willSet
- didSet
willSet - ๊ฐ์ด ์ ์ฅ๋๊ธฐ ์ ์ ํธ์ถ
didSet - ์๋ก์ด ๊ฐ์ด ์ ์ฅ๋ ํ์ ํธ์ถ
willSet
setter์ ๋ง์ฐฌ๊ฐ์ง๋ก ํ๋ผ๋ฏธํฐ ์ง์ ํ์ง ์์ผ๋ฉด ๊ธฐ๋ณธ๊ฐ์ผ๋ก newValue ์ฌ์ฉ
didSet
setter์ ๋ง์ฐฌ๊ฐ์ง๋ก ํ๋ผ๋ฏธํฐ ์ง์ ํ์ง ์์ผ๋ฉด ๊ธฐ๋ณธ๊ฐ์ผ๋ก oldValue ์ฌ์ฉ
์์๋ฅผ ํตํด ์ดํด๋ณด์
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
// About to set totalSteps to 200
// Added 200 steps
stepCounter.totalSteps = 360
// About to set totalSteps to 360
// Added 160 steps
stepCounter.totalSteps = 896
// About to set totalSteps to 896
// Added 536 steps
willSet๊ณผ didSet์ ๊ฐ ๋ณ๋์ ํตํด ํธ์ถ๋๋ ์์๋ฅผ ํ์ธํ ์ ์๋ค.
ํ๋กํผํฐ ์ต์ ๋ฒ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ํ๋กํผํฐ์ ๊ฐ์ด ๋ฐ๋์ ์ด๊ธฐํ๋์ด ์์ด์ผ ํ๋ฉฐ init()ํจ์ ์์์ ๊ฐ ํ ๋น์์๋ didSet๊ณผ willSet์ด ํธ์ถ๋์ง ์๋๋ค.
willSet๊ณผ didSet์ ํ์ฉ
๊ฐ์ฅ ๋น๋ฒํ๊ฒ ์ฌ์ฉ๋๋ ๊ณณ์ Model์์ ๊ฐฑ์ ๋ ๊ฐ์ View์๊ฒ ๋ณด์ฌ์ค ๋๋ค. ์ด๋ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ ์ฐธ์กฐ๋ฅผ ํตํด ๋งค๋ฒ ๊ฐ์ ๊ฐฑ์ ํ๋ ๊ฒ์ด ์๋๋ผ ์๋์ผ๋ก ๊ฐ์ ๊ฐฑ์ ํ ์ ์๋ค.
Type Property
์์ ์ ์์์ type property๋ ํ๋กํผํฐ์ ํ์ ์ ์ฐ๊ฒฐํ๋ค๊ณ ํ์๋ค. ๋ํ ์ธ์คํด์ค ํ๋กํผํฐ๋ ์ธ์คํด์ค์ ์ํ ํ๋กํผํฐ๋ฅผ ์๋ฏธํ๋ ๊ฒ์ฒ๋ผ ํ์ ํ๋กํผํฐ๋ ํ์ ์ ์ํ ํ๋กํผํฐ๋ค. ํ์ ์ ํด๋นํ๋ ํ๋์ ํ๋กํผํฐ๋ง ์์ฑํ์ฌ ๋ชจ๋ ์ธ์คํด์ค์ ๊ณตํต์ผ๋ก ์ฌ์ฉ๋๋ ๊ฐ์ ์ ์ํ๊ณคํ๋ค.
์์๋ฅผ ํตํด ์ดํด๋ณด์
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
}
}
์คํธ .. ๋๊ฒ ์ ๊ธฐํ๊ฒ ์๊ฒผ๋ค. ํด๋์ค ์๋ ์๋ธ ํด๋์ค์์ var(๋ณ์)๋ก ์ ์ธ๋์๋ค. class ํ์ ์ ๋ฐ๋ฅด๊ณ ์๊ณ ์ค๋ฒ๋ผ์ด๋๊ฐ ๊ฐ๋ฅํ๋ค.
'IOS๐ > iOS+Swift' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[iOS] Layout ์ ๋ฆฌ (0) | 2021.04.27 |
---|---|
[iOS] UIScene, UIWindowScene, UISceneSession (0) | 2021.04.16 |
[Swift] Closure์ ๋ํด ์์๋ด ์๋ค. (0) | 2021.04.16 |
[iOS] Notification๊ณผ NotificationCenter (0) | 2021.04.16 |
[iOS] iOS13์ดํ์ AppDelegate์ SceneDelegate (0) | 2021.04.07 |
๋๊ธ