Swift - 구조체와 클래스

luminoux·2022년 6월 29일
0

Swift 문법

목록 보기
8/8
post-thumbnail

구조체와 클래스

  • 구조체와 클래스는 프로그래머가 데이터를 용도에 맞게 묶어 표현하고자 사용.
  • 구조체는 value Type이고, 클래스는 Instance reference Type.
  • 비슷한 듯 하면서도, 많은 차이를 가지고 있다.

1.1. 구조체 (Structure)

  • 구조체는 struct 키워드로 정의.
  • 대문자 카멜케이스를 사용하여 이름을 지어준다.
struct 구조체 이름 {
	propertie & method
}
// People이라는 구조체 생성
// name과 age를 프로퍼티로 가진다.
struct People {
    var name: String
    var age: Int
}

1.2. 구조체 인스턴스 생성 및 초기화

멤버 와이즈 이니셜라이저를 사용.

  • 구조체를 상수 let으로 선언하면 인스턴스 내부의 Propertie를 변경 불가
  • 구조체를 변수 var로 선언하면 인스턴스 내부의 Propertie를 변경 가능
struct People {
    var name: String
    var age: Int
}

// var로 구조체 선언
var lumi = People(name: "Lumi", age: 25)
lumi.age = 26 // 변경가능
lumi.name = "luminoux"
    
// let으로 구조체 선언
let asher = People(name: "Asher", age: 30)
//asher.age = 31 변경 불가능

2.1. 클래스 (Class)

  • class 라는 키워드를 사용.
  • 클래스를 정의한다는 것은 새로운 타입을 생성해주는 것과 마찬가지이다.
  • 대문자 카멜케이스를 사용하여 이름을 지어야 한다..
class 클래스이름: 부모클래스 이름 {
	Properties & method
}
// Person class 생성
class Person {
    var height: Float = 0.0
    var weight: Float = 0.0
}

2.2. 클래스 인스턴스의 생성과 초기화

클래스를 정의한 후, 인스턴스를 초기화하고자 할 때는,
기본적인 이니셜라이저를 이용합니다.
만약 위의 Person구조체처럼 Property의 기본값이 지정되어 있으면
전달인자를 통해 따로 초깃값을 저장해주지 않아도 됩니다.

// Person class 생성
class Person {
    var height: Float = 0.0
    var weight: Float = 0.0
}

var lumi: Person = Person()
lumi.height = 175
lumi.weight = 77

let jogyul: Person = Person()
jogyul.height = 168
jogyul.weight = 100

기본 이니셜라이저 외에 사용자가 직접 이니셜라이저를 정의할 수도 있습니다.


2.3. 클래스 인스턴스의 소멸

클래스의 인스턴스는 참조타입이므로 더는 참조할 필요가 없을 때,
메모리에서 해제됩니다. 이를 소멸이라고 합니다.
클래스가 소멸되기 직전 deinit이라는 메서드가 호출됩니다.
이를 디이니셜라이저라고 부릅니다.

// Person class 생성
class Person {
    var height: Float = 0.0
    var weight: Float = 0.0
    
    deinit {
        print("Person 클래스의 인스턴스가 소멸됩니다.")
    }
}
var lumi: Person? = Person()
lumi = nil // Person 클래스의 인스턴스가 소멸됩니다.

3. 구조체와 클래스의 차이

구조체와 클래스의 같은 점과 다른 점

같은점

  • 값을 저장하기 위해 프로퍼티를 사용할 수 있습니다.
  • 기능 실행을 위해 메서드를 정의할 수 있습니다.
  • 서브스크립트 문법을 통해 구조체 또는 클래스가 갖는 값에 접근하도록 서브스크립트를 정의할 수 있습니다.
  • 이니셜라이저를 사용할 수 있습니다.
  • extension을 통한 확장이 가능합니다.
  • 특정 프로토콜을 준수할 수 있습니다.

다른점

  • 구조체는 상속할 수 없습니다.
  • 타입캐스팅은 클래스의 인스턴스에만 허용됩니다.
  • 디이니셜라이저는 클래스의 인스턴스에만 활용할 수 있습니다.
  • 참조 횟수 계산(Reference counting)은 클래스의 인스턴스에만 적용됩니다.

3.1. 값 타입과 참조 타입

참조란 주소값이 전달된다는 의미 입니다.
C언어 C++ 등의 언어에서의 포인터와 매우 유사한 개념입니다.

struct People {
    var name: String
    var age: Int
}

class Person {
    var name: String = "" 
    var age: Int = 0
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

// 구조체 생성
var structLumi = People(name: "structLumi", age: 25)

var cloneStruct = structLumi

structLumi.name = "jogyul" 
print(cloneStruct.name) 
//StructLumi의 name이 바뀌어도 바뀌지 않습니다.

// 클래스 생성
var classLumi = Person(name: "Lumi", age: 25)

var cloneClass = classLumi

classLumi.name = "jogyul"
print(cloneClass.name) 
// classLumi의 name이 바뀌면 바뀝니다. 
// 참조를 했기 때문입니다.

식별 연산자


클래스의 인스턴스끼리 참조가 같은지 확인할 때는 식별 연산자를 사용합니다.

class Person {
    var name: String = "" 
    var age: Int = 0
}

var personOne = Person()
var personTwo = personOne
var personThree = Person() // 새로운 인스턴스 생성

print(personOne === personTwo) // True 같은 인스턴스
print(personTwo === personThree) // False 다른 인스턴스

3.2. 스위프트의 모든 기본 데이터타입 -> 구조체

public struct String {
	// 	중략
    public init()
}

swift의 모든 데이터타입 (Int, String, Bool, Array, Dictionary...)
구조체로 이루어져 있습니다.
이는 곳 기본 데이터 타입은 모두 값 타입이라는 의미입니다.


4. 구조체와 클래스 선택해서 사용하기

애플의 가이드라인에서 다음 조건 중 하나 이상에 해당한다면,
구조체를 사용하는 것을 권장합니다.

  • 연관된 간단한 값의 집합을 캡슐화하는 것만이 목적일 때
  • 캡슐화한 값을 참조하는 것보다 복사하는 것이 합당할 때
  • 구조체에 저장된 프로퍼티가 값 타입이며 참조하는 것보다 복사하는 것이 합당할 때
  • 다른 타입으로부터 상속받거나 자신을 상속할 필요가 없을 때
profile
Apple Developer Academy @ Postech 2022

0개의 댓글