Property
클래스, 구조체 안의 속성
Stored Properties
var name : Type = DefaultValue
let name : Type = DefaultValue
class Person {
let name : String = "John Doe"
var age : Int = 33
}
Explict Member Expression
인스턴스 다음 .을 통해 접근하고자 하는 속성에 접근 Dot Syntax(점 문법)이라고도 부르며 스위프트에서는 Explict Member Expression(명시적 멤버 표현식)이라고 부름
구조체 인스턴스를 상수에 저장하면 구조체에 포함된 모든 속성이 상수가 됨 -> 구조체의 가변선은 속성의 가변성에 영향을 줌
instanceName.propertyName
instanceName.peopertyName = NewValue
class Person {
let name : String = "John Doe"
var age : Int = 33
}
let p = Person()
p.name
p.age = 30
struct Person {
let name : String = "John Doe"
var age : Int = 33
}
var p = Person()
p.age = 30
Lazy Stored Properties
저장속성이 초기화 되는 시점 = 인스턴스 초기화 시점과 같음, 하지만 지연 저장 속성에 처음 접근하는 시점에 초기화
인스턴스가 초기화 된 시점 후 개별적으로 초기화 -> 항상 변수 저장 속성으로 선언
생성자에서 초기화 하지 않기 때문에 선언시점에 기본값을 저장
lazy var name : Type = DefaultValue
struct Image {
init() {
print("new image")
}
}
struct BlogPost {
let title : String = "Title"
let content : String = "Content"
lazy var attachment : Image = Image()
let date : Date = Date()
lazy var formattedDate : String = {
let f = DateFormatter()
f.dateStyle = .long
f.timeStyle = .medium
return f.String(from : date)
}()
}
var post = BlogPost()
post.attachment // new image
Computed Properties
수학적 계산이 아닌 다른 속성을 기반으로 속성값이 결정됨, 저장속성은 값을 저장할 메모리 공간을 가지고 있으나 계산 속성은 메모리 공간이 없음
대신 다른 속성에 저장된 값을 읽어 필요한 계산을 실행 후 리턴하거나 속성으로 전달된 값을 다른 속성에 저장 -> 속성에 접근할 때 마다 다른 값이 리턴 될 수 있어 var로 선언
저장속성과 달리 선언 시점에 기본값을 저장할 수는 없음
getter, setter를 사용하려면 그 연산된 값을 저장할 변수가 반드시 있어야함
var name : Type {
get { //get block getter
statements
return expr
}
set(name) { //set block setter
statements
}
}
class Person {
var name : String
var yearOfBirth : Int
init(name : String, year : Int) {
self.name = name
self.yearOfBirth = year
}
var age : Int {
get {
let calendar = Calendar.current
let now = Date()
let year = calendar.component(.year, from : now)
return year - yearOfBirth
}
set {
let calendar = Calendar.current
let now = Date()
let year = calendar.component(.year, from : now)
yearOfBirth = year - newValue
}
}
}
let p = Person(name : "John Doe", year : 2002)
p.age // 17
p.age = 50
p.yearOfBirth // 1969
Person 인스턴스를 p에 저장하고 이름과 년도를 저장할 경우 변수 age는 현재 날짜를 구한뒤 상수 year에 넣고 year(현재년도) - yearOfBirth(2002) 를 뺀 결과인 17이 나오고 이는 getBlock 만 실행하게 됨
age에 50을 넣게 되면 setBlock을 실행시키고 상수 year(현재년도) - newValue(새로운 나이 50)의 결과인 1969를 리턴
Read - only Computed Properties
읽기전용 계산 속성으로 쓰기전용 계산 속성은 없음
var name : Type {
get {
statements
return expr
}
}
var name : Type {
statements
return expr
}
클로져와 구별하는 방법은 자료형 뒤에 할당 연산자가 있다면 클로져, 없다면 읽기전용 계산 속성
var age : Int {
get {
let calendar = Calendar.current
let now = Date()
let year = calendar.component(.year, from : now)
return year - yearOfBirth
}
}
Property Observer
willSet - 값이 저장되기 직전에 호출, didSet - 새로운 값이 저장된 직후 호출
저장 속성에만 가능 -> 예제 width는 저장 속성
var name : Type = DefaultValue {
willSet(name) {
statements
}
didSet(name) {
statements
}
}
class Size {
var width = 0.0 {
willSet {
print(width, =>, newValue)
}
didSet {
print(oldValue, =>, width)
}
}
}
let s = Size()
s.width = 123
// 0.0 => 123.0
// 0.0 => 123.0
Type Property
형식속성은 기본적으로 지연속성 -> 속성에 처음 접근하는 순간 초기화됨
Stored Type Properties
static var name : Type = DefaultValue // Variable Stored Type Property
static let name : Type = DefaultValue // Constant Stored TYpe Property
TypeName.propertyName
class Math {
static let pi = 3.14
}
let m = Math() // 이 순간 초기화가 아닌
m.pi // Error
Math.pi // 접근하는 순간 초기화 됨
Computed Type Properties
subclass 에서 overriding금지, class는 overriding 허용
static var name : Type {
get {
statements
return expr
}
set(name) {
statements
}
}
class var name : Type {
get {
statements
return expr
}
set(name) {
statements
}
}
enum Weekday : Int {
case sunday = 1, monday, tuesday, wednesday, thursday, friday, saturday
static var today : Weekday {
let cal = Calendar.current
let today = Date()
let weekday = cal.component(.weekday, from : today)
return Weekday(rawValue : weekday)!
}
}
Weekday.today
Self
self는 현재 인스턴스에 접근하기 위해 사용하는 특별한 속성
self를 타입 맴버에서 사용하면 인스턴스가 아닌 형식 자체를 나타냄
self
self.propertyName
self.method()
self.[index]
self.init(parameters)
class Size {
var width = 0.0
var height = 0.0
func calcArea() -> Double { // 속성에 접근할 시 생략
return (self.)width * (self.)height
}
var area : Double { // 메소드에 접근할 시 생략
return (self.)calcArea()
}
func update(width : Double, height : Double) // 속성과 파라미터 구분을 위해서 사용
self.width = width
self.height = height
func doSomething () { // 클로저 내부에서 속성에 접근할 때 사용
let c = { self.width * self.height }
}
static let unit = ""
static func doSomething() { // self를 타입 맴버에서 사용하면 인스턴스가 아닌 형식 자체를 나타냄
self.width // Error / 형식메소드에서 인스턴스 속성에 직접 접근하는 것은 불가능
(self.)unit
}
}
struct Size {
var width = 0.0
var height = 0.0
mutating func reset(value : Double) {
width = value
height = value
self = Size(width : value, height : value) // 인스턴스가 새로운 인스턴로 교체
// 생성자를 통해 초기화 가능 클래스에서는 불가능
}
}
'스피드 문법정리' 카테고리의 다른 글
17. Inheritance and Polymorphism (0) | 2020.06.19 |
---|---|
16. Method and Subscript (0) | 2020.06.19 |
14. Structure and Class (0) | 2020.06.18 |
13. Enumeration (0) | 2020.06.17 |
12. Collection (0) | 2020.06.16 |