Swift 구조체와 클래스

구조체

struct 구조체명 {
    프로퍼티와 메서드들
}

  • 구조체명에는 대문자 CamelCase를 사용한다.
  • 구조체 내부의 프로퍼티와 메서드는 소문자 camelCase를 사용한다.
  • 사용자 정의 생성자(생성자, initializer: 구조체가 생성될 때 호출되는 함수)가 없다면 자동으로 생성되는 memberwise 생성자를 사용한다.
  • 프로퍼티에 접근할 때는 comma(.)를 사용한다.
  • 구조체의 인스턴스는 값 타입이다. let으로 선언하면 인스턴스 내부의 프로퍼티를 변경할 수 없다.
  • 클래스처럼 소멸자(deinitializer)가 필요하지 않다.
  • Swift의 기본 데이터 타입(Int, Array, Set 등)은 구조체이기 때문에 기본 데이터 타입으로 선언된 변수(인스턴스)는 값 타입이며 전달 인자를 통해 전달된 값은 함수 내부에서 복사되어 사용된다.(call by value)

struct Info {
    var name: String        //property, member 변수
    let age: Int

/*
    init(name: String, age: Int) {    //memberwise 생성자 - 따로 작성하지 않아도 자동으로 생성된다
        self.name = name                //초기화해주는 역할. self는 자기자신
        self.age = age
    }
*/

}

var infoA: Info = Info(name: "Kim", age: 23)    //infoA가 인스턴스(객체). 괄호 안이 생성자를 호출하는 것.

클래스

class 클래스명 {
    프로퍼티와 메서드들
}
class 클래스명: 부모클래스명 {
    프로퍼티와 메서드들
}

  • 자료형이기 때문에 클래스명은 대문자 CamelCase를 사용한다.
  • 부모클래스를 상속받을 때는 콜론(:) 뒤에 부모클래스를 명시한다.
  • 인스턴스 생성 및 초기화시 생성자를 사용한다. 구조체처럼 자동으로 생성되는 memberwise 생성자가 없다.
  • 프로퍼티에 접근할 때 comma(.)를 사용한다.
  • 클래스의 인스턴스는 참조 타입이다.(메모리 주소를 가진다) 구조체의 인스턴스를 상수 let으로 선언해도 인스턴스 내부의 프로퍼티를 변경할 수 있다. 주소는 항상 고정되기 때문에 주소가 가리키는 프로퍼티는 변경할 수 있다.
  • 클래스 인스턴스 소멸: 인스턴스가 메모리에서 해제되기 직전 처리해야 할 코드를 소멸자에 정의한다.
  • 소멸자(deinitializer): 클래스당 하나만 존재, 매개변수와 반환값이 없음, 소괄호 없음
  • nil값을 가지면 어떠한 메모리도 가리키지 않기 때문에 클래스 인스턴스가 메모리에서 소멸된다.

class Person {
    var height: Float = 0.0
    var weight: Float = 0.0
    //기본 생성자 재정의
    init() {
        self.height = 10.0
        self.weight = 20.0
    }
    //memberwise 생성자
    init(height: Float, weight: Float) {
        self.height = height
        self.weight = weight
    }
    //사용자 정의 생성자
    init(a: Float) {
        self.height = a
        self.weight = a
    }
    //소멸자 재정의
    deinit {
        print("Person class instance is deinitialized")
    }
}

var personA: Person = Person()    // 기본 생성자를 통해 인스턴스 초기화 10.0, 20.0
personA.height = 123.4
personA.weight = 123.4

var personB: Person = Person(height: 123.4, weight: 123.4) //memberwise 생성자 이용
var personC: Person = Person(a: 123.4)    //사용자 정의 생성자 이용
var personD: Person? = Person()
personD = nil    //클래스의 인스턴스가 메모리에서 소멸됨(소멸자 호출)

구조체와 클래스 비교

공통점 차이점
  • 프로퍼티와 메서드를 정의할 수 있다.
  • 프로퍼티에 접근할 수 있도록 서브스크립트를 정의할 수 있다.
  • 생성자를 정의할 수 있다.
  • extension을 통해 확장할 수 있다.
  • 특정 기능을 실행하기 위해 특정 프로토콜을 따를 수 있다.
  • 구조체는 상속이 불가능하다.
  • 구조체의 인스턴스는 값(value) 타입, 클래스의 인스턴스는 참조(reference) 타입이다.
     -형 변환은 클래스의 인스턴스만 가능하다.
     -소멸자는 클래스에만 있다.
     -참조 횟수 계산(reference counting)은 클래스의 인스턴스에만 있다.