* 2023년 Apple Developer Academy @ POSTECH 에서 swift 스터디를 하며 공부한 내용입니다
1. 변수/프로퍼티의 개념
변수의 개념
- 프로그램에서 데이터를 저장하는 메모리 공간
- 이름, 형, 메모리 주소, 값, 영역 등으로 특성을 구분지어 볼 수 있음
var number1 : Int = 20
- 이름 = 변수를 구분하기 위해 사용 ⇒ number1
- 고유 이름을 ‘식별자’(Identifier)’라고 함
- 형 = 타입 = 데이터의 자료형 ⇒ Int
- 값 = 변수에 들어가는 데이터 ⇒ 20
- 영역 = 변수가 사용 가능한 범위
변수와 상수
변수
- 변할 수 있는 값을 저장
- var 변수명 : 데이터 타입 = 값
- 데이터 타입은 생략 가능
상수
- 변하지 않는 일정한 값을 저장
- let 상수명 : 데이터 타입 = 값
- 데이터 타입 생략 가능
프로퍼티의 개념
- 클래스(class), 구조(structure), 혹은 열거형(enumeration) 등의 특정 인스턴스와 관련된 값
- dot notation syntax를 사용하여 접근하거나 수정할 수 있음
class MyClass {
static var numberOfInstances = 0
init() {
MyClass.numberOfInstances += 1
}
static var currentNumberOfInstances: Int {
return numberOfInstances
}
}
let instance1 = MyClass()
let instance2 = MyClass()
print(MyClass.currentNumberOfInstances) // Output: 2
❓ 변수와 프로퍼티의 차이?
- 영역
- 변수: 함수와 같이 특정 코드 블록 안에서 사용/선언될 수 있음
- 프로퍼티: 해당 인스턴스를 참조하는 어떤 코드에 의해서든 접근/수정될 수 있음
- 접근 통제
- 변수: private, internal, public과 같이 어느 부분의 코드가 해당 변수에 접근할 수 있는지 결정할 수 있음
- 프로퍼티: 프로퍼티 그 자체가 아니라 프로퍼티와 관련된 getter 그리고/혹은 setter 메소드에 대한 접근을 통제하기 위해 사용
- 초기화
- 변수: 사용하기 전에 무조건 초기화되어야 함
- 프로퍼티
- 생성자(initializer)를 통해서 초기 값을 초기화
- 초기 값이 제공되지 않는다면 기본 값을 통해서 자동적으로 초기화
- 용도
- 변수: 코드 블록 안에서 임시 값 혹은 중간 값을 담기 위해 사용
- 프로퍼티: 타입의 인스턴스와 관련하여 값을 저장하거나 검색하기 위해 사용
2. 변수/프로퍼티의 종류
변수의 종류
- 영역/메모리 기준
- 지역 변수
- 블록(ex - 함수)내에서 선언되어 블록 내에서만 사용할 수 있는 변수
- 처리가 끝난 이후에는 해당 변수 이용 불가
- 상위 혹은 다른 블록에 같은 이름의 변수가 있더라도 메모리 공간이 다르므로 다른 변수임
- 전역 변수
- 프로그램 내 전체에서 사용 가능한 변수
- 매개 변수
- 다른 블록에 전달되는 변수
- 변수에 저장되어있는 값 뿐만 아니라, 해당 메모리 공간 자체를 활용하기 위하여 메모리 공간의 주소값을 이용 (포인터)
- 지역 변수
- 타입 기준
종류 | 설명 |
숫자형 변수 (Numeric variables) | - 정수, 부동소수점 숫자 등의 숫자 데이터를 저장하는 변수 - Int , Float , Double 등 |
문자형 변수 (Character variables) | - 단일 문자 데이터를 저장하는 변수 - Character |
문자열 변수 (String variables) | - 문자열 데이터를 저장하는 변수 - String |
불리언 변수 (Boolean variables) | - 논리값( true 또는 false )을 저장하는 변수 - Bool |
배열 변수 (Array variables) | - 여러 개의 데이터를 순차적으로 저장하는 변수 - Array |
구조체 변수 (Struct variables) | - 서로 다른 데이터 타입을 조합하여 새로운 데이터 타입을 만드는 데 사용되는 변수 - struct |
열거형 변수 (Enum variables) | - 서로 다른 유형의 값을 가진 데이터를 하나로 묶는 데 사용되는 변수 - enum |
옵셔널 변수 (Optional variables) | - 값이 없을 수 있는 데이터를 나타내는 변수 - Optional |
프로퍼티의 종류
저장 프로퍼티 (Stored Property)
struct Person {
var name: String
var age: Int
}
var john = Person(name: "John", age: 30)
print(john.age) // Output: 30
- 인스턴스 변수와 상수
- 값을 저장할 때 사용
- 초기값을 설정 할 수 있고, 클래스 구조체에서는 인스턴스와 연관된 값을 저장함.
- 구조체, 클래스에서만 사용 가능
- 지연 저장 프로퍼티: lazy var
class Position {
lazy var point: CoordinatePoint = CoordinatePoint()
}
- 호출 되기 전에 값 초기화X
- 불필요한 성능 저하, 메모리 사용 감소
- 클래스 구조체에만 사용 가능
- lazy 키워드를 선언 앞에 작성해서 사용함.
- 상수(let)에는 사용 금지 → 상수는 인스턴스가 완전히 생성되기 전에 초기화 해야하므로 어울리지 않음
연산 프로퍼티 (Computed Property)
struct Rectangle {
var width: Double
var height: Double
var area: Double {
return width * height
}
}
var rect = Rectangle(width: 5.0, height: 10.0)
print(rect.area) // Output: 50.0
- 실제로 값을 저장하지는 않고, get과 set 키워드로 값을 간접적으로 설정하거나 받는 프로퍼티
- 일반적으로 다른 연산이나 다른 프로퍼티를 기반으로 값을 얻어내기 위해 사용
- 클래스 구조체 열거형에도 사용
- getter
struct Circle {
var radius: Double
var area: Double {
get {
return Double.pi * radius * radius
}
}
}
var circle = Circle(radius: 5.0)
print(circle.area) // Output: 78.53981633974483
- 인스턴스 내부, 외부의 값을 연산하여 적절한 값을 돌려주는 역할
- 연산된 값을 저장할 프로퍼티가 있어야 함(필수는 아니지만 일반적)
- setter
class Car {
private var _fuelLevel: Double = 0.0
var fuelLevel: Double {
get {
return _fuelLevel
}
set {
_fuelLevel = min(max(0.0, newValue), 1.0)
}
}
}
var car = Car()
car.fuelLevel = 0.5 // call the setter method
print(car.fuelLevel) // Output: 0.5
- 프로퍼티 값을 간접적으로 설정하는 역할(내부가 은닉화된 경우 유용)
- 은닉화: 외부에서 객체 내부의 접근/수정 권한을 막은 것
- 매개변수 이름을 생략 하면 newValue를 통해 접근 가능
타입 프로퍼티 (Type Property)
struct AudioChannel {
static let level = 10
static var maxLevel = 0
}
print(AudioChannel.level)
print(AudioChannel.maxLevel)
- 인스턴스의 속성이 아닌, 타입에 따른 속성을 정의할 수 있음
- 인스턴스가 아니라, 특정 타입에서 사용함
- 따라서 타입 자체에 속하는 프로퍼티이며, 값이 고유함
- 모든 인스턴스가 공통으로 사용하는 값에 사용
- 저장 프로퍼티, 연산 프로퍼티 모두 사용 가능
- static 키워드를 사용해서 값 타입에서 타입 프로퍼티를 설정할 수 있음
- class 키워드를 사용해서 클래스 타입에서 타입 프로퍼티를 설정할 수 있음
- 값을 가져올때는 클래스의 이름을 통해서 가져올 수 있음
프로퍼티 옵저버 (Property Observer)
class Account {
var credit: Int = 0 {
willSet {
print("잔액이 \\(credit)에서 \\(newValue)원으로 변경될 예정입니다.")
}
didSet {
print("잔액이 \\(oldValue)에서 \\(credit)원으로 변경되었습니다.")
}
}
}
let myAccount = Account()
myAccount.credit = 1000
- 프로퍼티의 값이 변경 될 때 지정된 코드를 실행
- 프로퍼티 옵저버를 사용하려면, 값이 반드시 초기화되어있어야 함
- 현재와 같은 값을 할당하더라도 프로퍼티 옵저버는 호출됨
- Lazy 프로퍼티에는 사용될 수 없고, 저장 프로퍼티에서만 사용 가능
- 연산 프로퍼티에는 사용 불가능
- 하지만 상속받은 연산 프로퍼티에는 override를 통해 사용 가능하다. 즉, 부모 클래스에 연산프로퍼티가 있다. 여기서는 프로퍼티 옵저버를 사용 못하지만, 상속받은 자식클래스에서는 이 프로퍼티를 override 하여 프로퍼티 옵저버를 정의하여 사용할 수 있다.
- Property의 값이 변경되기 직전에 willSet이 호출되고, 변경된 직후에는 didSet이 호출됨
- willSet에서는 newValue가, didSet에서는 oldValue가 자동으로 전달됨
3. 변수/프로퍼티의 역할
변수의 역할
- 데이터 저장
- 변수는 메모리에 데이터를 저장
- ex-사용자의 이름, 나이, 전화번호 등
- 데이터 조작
- 변수는 저장된 데이터를 읽거나 수정
- ex-사용자의 나이를 증가시키거나 전화번호를 변경
- 데이터 전달
- 변수는 프로그램 내에서 데이터를 전달하는 데 사용
- ex-한 함수에서 다른 함수로 데이터를 전달하거나 뷰 컨트롤러에서 뷰로 데이터를 전달
- 코드의 재사용
- 변수는 값을 저장하고 다시 사용할 수 있으므로 코드의 재사용성을 높여줌
- ex-사용자의 이름을 여러 곳에서 사용
- 프로그램의 상태 관리
- 변수는 프로그램의 상태를 관리하는 데 사용
- ex-게임에서 현재 점수를 저장하거나 애플리케이션에서 사용자가 마지막으로 방문한 페이지를 저장
프로퍼티의 역할
: 프로퍼티는 모델 데이터와 동작을 정의하기 위한 유연하고 강력한 방법을 제공
- 값 저장/검색
- 캡슐화
- 데이터 혹은 동작을 캡슐화할 수 있는 방식 제공
- 외부 코드가 직접 내부 인스턴스의 상태에 대해 접근하거나 수정하는 것을 방지
- 옵저버
- 옵저버: 사람이 프로퍼티의 값의 변화에 응답하도록 허용
- willSet: 값이 설정되기 전에 호출
- didSet: 값이 설정된 후에 호출
- 프로퍼티의 값이 변화할 때 추가적인 액션을 수행
- Type-level behavior
- 동작의 타입 그 자체와 관련하여 동작을 정의
반응형
'⌨️ Language > swift' 카테고리의 다른 글
[Swift] 콜렉션 타입 (0) | 2024.03.16 |
---|---|
[Swift] 변수와 프로퍼티2 (1) | 2024.03.15 |
[Swift] Escaping Closure (1) | 2023.05.20 |
[Swift] 접근 제어 (Access Control) (0) | 2023.02.07 |
[Swift] ARC (0) | 2023.02.07 |
댓글