일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 글또9기
- K디지털기초역량훈련
- ios 개발 강의
- 내_삶
- error해결
- avaliable
- uikit
- unrecognized selector sent to class
- 생명주기
- AnyObject
- Switch
- IOS
- 회고
- 글또
- copy-on-write
- SWIFT
- 다짐글
- 바이트디그리
- 제어전송문
- actionSheet
- MyLife
- On branch is up to date with ' '
- 주간 달력
- struct
- Git
- weekly calendar
- 코드스니펫
- 파스칼표기법
- class
- 연관값
- Today
- Total
seong_hye, the developer
Swift) 문법 정리 - 속성(Property) & 함수(Method) 본문
구조체와 클래스는 둘 다 속성과 메서드로 이루어져 있는데
둘의 차이는 상속과 연관이 있는 메서드에서 차이가 나게 된다.
이를 제대로 알아보기 위해
속성과 함수에 대해 자세히 알아보도록 하자
속성
저장 속성(Stored Properties)
값이 저장되는 일반적인 속성(변수)
클래스/구조체의 틀에서 찍어낸 각 인스턴스가 가지는 고유의 데이터 저장 공간
변수(var)나 상수(let)로 선언 가능
객체의 초기화 시, 각 저장 속성은 반드시 값을 가져야 함
(기본값 설정 or 생성자에서 설정 or 옵셔널 타입으로 선언)
struct Person {
var name = "seonghye"
var age: Int?
}
지연 저장 속성(Lazy Stored Properties)
해당 속성이 반드시 처음부터 초기화가 필요하지 않은 경우에 초기화를 지연시킴
값에 대한 접근이 있어야 초기화(메모리 공간 생성)
lazy var로만 선언 가능
생성자에서 초기화하지 않기 때문에 반드시 기본값이 필요
사용하는 이유?
- 메모리 공간의 낭비를 막을 수 있음
- 지연 저장 속성으로 선언되는 속성이 다른 저장 속성을 이용해야 할 때
struct Person {
var num = 1
lazy var name = "seonghye"
lazy var age = {
return num * 24
}
}
계산 속성(Computed Properties)
속성의 형태를 가진 실질적 메서드 ( getter / setter )
메서드이기 때문에 인스턴스에 메모리 공간이 할당되어 있지 않음
var로만 선언 가능, 자료형까지 선언해야함
- get블록만 선언하면 읽기 전용(read-only) 계산 속성이 됨(필수 구현)
- set 블록은 선택적으로 구현할 수 있음( set만 구현하는 것은 불가능)
- set 블록에서 기본 파라미터 newValue가 제공됨 -> 받아오는 값
struct Person {
var birth: Int = 0
var age: Int {
get {
return 2024 - birth
}
set(age) {
self.birth = 2024 - age
}
}
}
var seonghye = Person()
seonghye.birth = 2000
seonghye.age // 24 (get 블록 실행)
seonghye.age = 23 //(set 블록 실행)
seonghye.birth // 2001
타입 속성(Type Properties)
인스턴스에 속한 속성이 아니고 ,타입 자체가 속한 속성이기에
내/외부에서 Type.property로 접근해야함
저장 타입 속성을 주로 사용
어떤 경우에 선언하는가?
- 모든 인스턴스가 동일하게 가져야 하는 보편적인 속성
- 모든 인스턴스가 공유해야 하는 성격
1. 저장 타입 속성
static 키워드 사용 -> 상속시 재정의 불가
let/ var 선언 둘 다 가능
항상 기본값(초기값) 필요
자체적으로 지연(lazy) 속성의 성격을 가지므로, 호출시 메모리 할당
struct Circle {
static let pi: Double = 3.14
static var count: Int = 0
}
Circle.pi //3.14
Circle.count //0
2. 계산 타입 속성
static(고정적인) 또는 class 키워드 사용
(static: 상속시 재정의 불가 / class: 상속시 재정의 가능)
var 키워드만 사용 가능
메서드이기 때문에 메모리 공간이 할당되어 있지 않음
struct Circle {
static let pi = 3.14
...
static var multiPi: Double {
return Circle.pi * 2
}
}
let result = Circle.multiPi
(저장) 속성 감시자(Property Observers)
저장 속성의 변화시점을 관찰하는 실질적 메서드(타입/인스턴스 둘 다 가능은 함)
willSet - (값이 변할 때) 새 값이 저장되기 직전에 호출됨
didSet - (값이 변할 때) 새 값이 저장된 직후에 호출됨
저장속성 자체는 var로만 선언 가능
자료형을 선언하는 것은 일반 변수와 동일
둘 중 하나만 선언하면 됨(일반적으로 didSet으로 구현)
변수가 변하면 어떤 것을 업데이트 하려는 패턴 구현할 때 사용
ex) 프로필 사진, 상태 메시지
속성 감시자 추가 가능한 경우?
- 저장 속성( 상속한 저장속성은 재정의 불가, 감시자 추가는 가능)
- 상속한 계산 속성을 재정의해 속성 관찰자 추가 가능(단순 메서드 추가일 뿐)
class Profile {
...
var statusMessage: String = "기본메시지" {
willSet {
print("\(statusMessage)에서 \(newValue)로 번경될 예정입니다")
}
didSet {
print("\(oldValue)에서 \(statusMessage)로 변경되었습니다")
}
}
}
+ print문 앞이 같은 이전 내용 / 뒤가 새로운 내용을 나타냄
메서드(Method)
인스턴스 메시지
가장 기본적인 메서드
메서드 접근 시 인스턴스 이름으로 접근해야 함
메서드이기 때문에 인스턴스에 메모리 공간이 할당되어 있지 않음
값 타입의 인스턴스 메서드에서 인스턴스 고유의 (저장) 속성을 수정할 수 없음
(수정하려면 명시정으로 mutating 키워드 필요)
+ 오버로딩 지원
struct Person {
var name = "seonghye"
func breathe() {
print("\(name)이 숨을 쉽니다")
}
}
타입 메서드
인스턴스에 속한 속성이 아니고, 타입 자체에 속한 속성이기 때문에
내/외부에서 Type.method()로 접근해야함
static 또는 class 키워드 사용
(static: 상속시 재정의 불가 / class: 상속시 재정의 가능)
메서드이기 때문에 인스턴스에 메모리 공간이 할당되어 있지 않음
사용하는 경우?
타입에 해당하는 보편적인 동작의 경우
class Dog {
static let species = "Dog"
...
static func saySpecies() {
print("종은 \(species)입니다")
}
}
Dog.saySpecies() // "종은 Dog입니다"
서브스크립트(Subscripts)
대괄호([ ])를 이용해서 접근가능하도록 만든 문법
(인스턴스) 서브스크립트
함수의 구현이 특별한 키워드인 subscript로 명명됨
메서드이기 때문에 인스턴스에 메모리 공간이 할당되어 있지 않음
메서드 접근 시, 인스턴스 이름으로 접근해야함 -> instance[파라미터]
메서드 실행 시, 스택프레임을 만들고 필요한 데이터를 사용 -> 메서드 종료 시 스택프레임 사라짐
파라미터 2개 이상도 구현 가능함
계산속성과 형태는 유사 -> 리턴 타입이 있는 부분이 다름
struct TimeTable {
var multiplier: Int = 3
subscript(index: Int) -> Int {
get {
return multiplier * index
}
}
}
let threeMultiplier: TimeTable = TimeTable()
print("6 X 3 을 하면 \(threeMultiplier[6])이 나옵니다") // "6 X 3 을 하면 18이 나옵니다"
struct Matrix {
// 2차원 배열
var data = [["1", "2", "3"], ["4", "5", "6"], ["7", "8", "9"]]
// 2개의 파라미터를 받는 읽지 전용 서브스크립트 구현
subscript(row: Int, column: Int) -> String? {
get {
if 2 < row || 2 < column {
return nil
}
return data[row][column]
}
}
}
var mat = Matrix()
mat[0, 1]! // "2"
타입 서브 스크립트
서브 스크립트 메서드 앞에 static 또는 class 키워드만 붙이면 됨
enum Planet: Int {
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
static subscript(n: Int) -> Self {
return Planet(rawValue: n)!
}
}
let planet = Planet[3]
switch planet {
case .mercury:
print("mercury 입니다")
case .venus:
print("venus 입니다")
case .earth:
print("earth 입니다")
case .mars:
print("mars 입니다")
case .jupiter:
print("jupiter 입니다")
case .saturn:
print("saturn 입니다")
case .uranus:
print("uranus 입니다")
case .neptune:
print("neptune 입니다")
} // "earth 입니다"
참고자료)
'IOS' 카테고리의 다른 글
Swift) 문법 정리 - 타입 캐스팅(Type Casting) / Any, AnyObject (0) | 2022.07.12 |
---|---|
Swift) 문법 정리 - 상속 (0) | 2022.07.12 |
Swift) 문법 정리 - 연산자 (0) | 2022.07.12 |
Swift) 문법 정리 - 클래스(Class) vs 구조체(Struct) (0) | 2022.07.12 |
Swift) 문법 정리 - 옵셔널(Optional) / 옵셔널 바인딩 (0) | 2022.07.12 |