클래스/구조체

  • 클래스: 프로퍼티와 메서드로 구성된 참조 타입이다.
  • 구조체: 프로퍼티와 메서드로 구성된 값 타입이다.

예시

class Dog {
    var name: String
    
    init(name: String) {
        self.name = name
    }
    
    func sit() {
        print("\(name) 앉았습니다.")
    }
}

// bori는 Dog 인스턴스를 참조하는 변수이다
// 클래스는 참조 타입이므로, 여러 변수가 하나의 인스턴스를 함께 가리킬 수 있다
// - bori 변수는 stack 영역에 생긴다
// - 실제 Dog() 데이터는 heap 영역에 생긴다
// - 즉 heap 영역에 만들어진 메모리 주소를 bori에 담는다
var bori = Dog(name: "보리")

구조체

struct Bird {
    var name: String

    func fly() {
        print("\(name) 날아갑니다.")
    }
}

// 구조체는 값 타입이므로 변수에 할당하거나 전달할 때 값이 복사된다
// 따라서 각각의 변수는 독립적인 데이터를 가진다
// - bird 변수는 stack 영역에 저장된다
// - 실제 Bird() 데이터는 스택에 저장된다
var bird = Bird()

타입 속성(Type Properties)

class Circle {
    static let pi = 3.141526
    static var count = 0
}
  • 인스턴스에 속한 속성이 아니고 타입 자체에 속한 속성으로 Type.property로 접근해야한다.
  • 저장 타입 속성(을 주로 사용)
    • 모든 인스턴스가 동일하게 가져야 하는 보편적인 속성
    • 모든 인스턴스가 공유해야하는 성격에 가까운 저장 속성을 의미
    • 자체적으로 lazy한 성격을 가지므로 호출 시 메모리 할당(내부적으로 Thread-Safe)
  • 계산 타입 속성
    • 상속 시 재정의 가능(class 키워드 사용 시)
    • 메서드이므로 타입에 메모리 공간이 할당되어 있지 않음

저장 속성(Stored Properties)

struct Bird {
    var name = "새"
    var weight = 0.0

    func fly() {
        print("날아갑니다.")
    }
}
  • 클래스/구조체의 틀에서 찍어낸 각 인스턴스가 가지는 고유의 데이터 저장 공간을 의미한다.
  • var나 let으로 선언 가능하다.
  • 객체의 초기화 시 각 저장 속성은 반드시 값을 가져야 한다.
  • 기본값을 설정하거나 생성자에서 설정하거나 옵셔널 타입으로 선언하여 nil을 초기값으로 가질 수 있다.
  • 메모리 공간을 가진다.
  • 참고: 열거형의 경우 메모리 공간이 필요한 저장 속성을 선언할 수 없다.

지연 저장 속성(Lazy Stored Properties)

lazy var view = UIImageView()
  • 해당 속성이 반드시 처음부터 초기화가 필요하지 않은 경우(메모리 공간을 많이 차지할 여지가 있는) 초기화를 지연시킨다.
  • 값에 대한 접근이 있어야 초기화(메모리 공간 생성)
  • lazy var 로만 선언 가능하다(lazy let 불가)
  • 생성자에서 초기화하지 않기 때문에 기본값이 필요하다.
  • 사용하는 이유
    • 메모리 공간의 낭비를 막기 위해
    • 지연 저장 속성으로 선언되는 속성이 다른 저장 속성을 이용해야 할 때

메서드

  • 코드 영역에서 어떤거를 실행할 지 명령어의 묶음이다.

메서드 호출 과정

class Dog {
    var name: String
    var weight: String
    
    init(name: String, weight: String) {
        self.name = name
        self.weight = weight
    }
    
    func sit() {
        print("\(name) 앉았습니다.")
    }

    func layDown() { }
}
  1. class Dog { … }을 정의하면
    • sit(), layDown() 같은 메서드는 -> 코드 영역에 저장됨
    • name, weight 같은 구조 정보는 -> 데이터 영역에 저장됨
  2. 객체를 만들 때
    • Heap에 Dog 객체 생성됨
    • name = “보리” 같은 실제 데이터가 여기 존재
    • Stack에는 bori 라는 변수에 힙 주소(참조값)가 저장됨
  3. 함수 호출
    • 함수를 실행하기 위한 임시 공간(스택 프레임) 생김
    • 이때 self라는 값이 들어옴(self = bori의 주소)
  4. 코드 영역의 함수 실행
    • bori 변수는 Dog 인스턴스의 주소를 가지고 있다.
    • 실제 메서드 탐색은 힙에 있는 Dog 인스턴스를 기준으로 이루어진다.
    • 인스턴스는 자신의 타입 정보(Dog)를 통해 sit() 메서드를 찾는다.
    • 해당 메서드의 실제 실행 위치(코드 영역)를 찾아간다.
  5. 함수 종료
    • sit()실행 종료 시 스택에 만들어진 실행 공간 사라진다.

계산 속성(Computed Properteis)

  • 속성의 형태를 가진 실질적 메서드
  • 다른 저장 속성에 의존한 결과로 나오는 메서드를 속성처럼 만든 것
  • 메서드이기 때문에 인스턴스의 메모리 공간이 할당되어 있지 않음
  • var 로만 선언 가능, 자료형까지 선언해야 한다.

Reference

  • https://junbok97.tistory.com/318