본문 바로가기
IOS - Swift

Swift 기초문법- struct와 class의 차이

by 게게겍 2022. 9. 14.

📖 struct과 class 차이

struct 는 복사 , class 는 공유
즉, struct 는 참조하는 값이 변경되어도 복제한 값이 바뀌는것이기에 기존의 값에 영향을 미치지 않습니다.
class 는 참조하는 값이 변경되면 원본과 복제값이 동일하기 떄문에 변경값이 영향을 미칩니다.

클래스 인스턴스가 인자로 사용될 때는 참조가 넘어가고 구조체는 값이 넘어간다

💬 유튜브를 처음 실행하였을때, 영상 하나하나에 해당되어 있는 영역에 나타내는 정보는 이름, 영상 썸네일, url, 조회수 등의 정보들이 있습니다. 이렇게 정해져 있는 데이터 종류를 하나하나 관리하기 힘들어, 프로그래밍에서는 하나의 모델 에 묶어두고 관리합니다.

이때, 데이터를 모델에 묶는 방식은 두 가지가 있습니다.

  • struct
  • class

새로운 클래스나 구조체를 선언할 때마다 Swift 에서 완전 새로운 타입을 선언하는 것입니다. 그래서 이름을 다른 표준 Swift 타입(String, Int, Bool)과 같이 UpperCamelCase 이름(SomeClass, SomeStructure 등)으로 선언합니다.
반대로 프로퍼티나 메소드는 lowerCamelCase(frameRate, incrementCount 등)으로 선언합니다.

📌 0. Class와 Struct의 비교

클래스와 구조체에는 많은 공통점이 있습니다.

  • 값을 정의하기 위한 프로퍼티 정의
  • 기능을 제공하기 위한 프로퍼티 정의
  • 기본 구현에서 기능을 확장
  • 특정한 표준 기능을 순응하기 위한 프로토콜 받아오기
  • subscript문법을 이용하여 특정값을 접근할 수 있는 subscript 정의
  • 초기상대의 initializer 정의

 

📌 1. struct (구조체)

struct 구조체 이름 { 구조체 내용 }

ex)

struct YoutuberStruct {
    var name : String
    var subscribersCount : Int
}

 선언한 구조체 내부에 두 가지 정보를 입력할 수 있습니다.

var coder = YoutuberStruct(name: "후니", subscribersCount: 1000)

원하는 정보를 담은 구조체를 coder 이라는 이름으로 선언했습니다.

var coderclone = coder

coder를  복제한 coderClone 을 선언합니다.

print("값 넣기 전 coderclone.name : \(coderclone.name)")

>>> 값 넣기 전 coderclone.name : 후니

coderClone 안의 name 값은 coder 동일합니다.

coderClone.name = "하하"

이제, coderClone 안의 name 값을 변경해봅시다.

print("값 넣은 후 coderClone.name : \(coderClone.name)")
print("값 넣은 후 coder.name : \(coder.name)")

>>> 값 넣은 후 coderClone.name : 하하
값 넣은 후 coder.name : 후니

결과를 확인해보면, coderClone 내부의 값이 변했음에도 원래의 값인 coder 는 변하지 않은것을 알게 되었습니다.

⭐️ struct는 복제하면 다른 개체 (영향 X)


📌 2. Class

class class 이름 { class 내용 }

ex)

struct YoutuberClass {
    var name : String
    var subscribersCount : Int
    
    // 메모리에 올린다! 시작한다! - 생성자
    // 두 변수에 값이 없음
    // init으로 매개변수를 가진 생성자 메소드를 만들어야
    // 매개변수를 넣어서 그 값을 가진 객체(object)를 만들 수 있다.
    
    init(name:String, subscribersCount: Int) {
        self.name = name // 외부에서 넘어오는 name 값을 넣을게요
        self.subscribersCount = subscribersCount
    }
}

💬 선언한 class 안에 두 가지 정보를 입력할 수 있습니다. (구조체와 달리 생성자가 있음을 확인)

var coder = YoutuberClass(name:"후니", subscribersCount: 99999)

var coderClone = coder

print("값 넣기 전 coderClone.name : \(coderClone.name)")

>>> 값 넣기 전 coderClone.name : 후니

💬 위에서와 같은 방식으로 coder 라는 class를 만들고 coderClone 안에 복제합니다.

coderClone.name = "후우니"

print("값 넣은 후 coderClone.name : \(coderClone.name)")

print("값 넣은 후 coder.name : \(coder.name)")

>>> 값 넣은 후 coderClone.name : 후우니
값 넣은 후 coder.name : 후우니

💬 struct와 달리, 복제한 class의 한 값에 참조해 변경하였을 때 기존 class의 값에도 변화가 있음을 알 수 있습니다.

⭐️ class 는 서로 연결이 되어있습니다. 같은 메모리 공간을 "공유" 하기에
본따서 똑같은 걸 만들고 한 쪽을 훼손하면, 다른 한 쪽도 훼손되며
내가 수정한 내용을 다른 사람들이 다 볼 수 있습니다.

💬 유튜브에서 내 영상의 정보를 수정하면, 다른 사람에게 똑같이 보여진다는 점을 생각하면 이해가 편합니다.

⭐️구조체에서는 가능하지 않고 클래스에서만 가능한 것들

  • 상속 (Inheritance) : 클래스의 여러 속성을 다른 클래스에 물려 줌
  • 타입 캐스팅 (Type casting) : 런타임에 클래스 인스턴스의 타입을 확인
  • 소멸자 (Deinitializers) : 할당된 자원을 해제(free up) 시킴
  • 참조 카운트 (Reference counting) : 클래스 인스턴스에 하나 이상의 참조가 가능

클래스와 구조체 모두 프로그램의 코드를 조직화 하고 특정 타입을 선언하는데 사용됩니다. 그렇다면 Struct와 Class는 각각 어떨때 사용해야 할까요?

일반적으로 다음의 조건 중 1개 이상을 만족하면 구조체를 사용한다고 합니다.

  • 구조체의 주 목적이 관계된 간단한 값을 캡슐화(encapsulate) 하기 위한 것인 경우
  • 구조체의 인스턴스가 참조되기 보다 복사되기를 기대하는 경우
  • 구조체에 의해 저장된 어떠한 프로퍼티가 참조되기 보다 복사되기를 기대하는 경우
  • 구조체가 프로퍼티나 메소드 등을 상속할 필요가 없는 경우
실 “예”를 들면 다음과 같습니다. double형을 갖는 widthheight를 캡슐화해 특정 지형의 크기로 사용하는 경우 Int형을 갖는 startlength를 캡슐화해 특정 값의 범위를 나타내는 경우 Double형으로 구성된 x, y, z를 캡슐화 해 3D 좌표 시스템의 point로 사용하는 경우
위에 기술된 경우를 제외한 다른 모든 경우에는 구조체가 아니라 클래스를 사용하면 됩니다.

https://jusung.gitbook.io/the-swift-language-guide/language-guide/09-classes-and-structures

'IOS - Swift' 카테고리의 다른 글

Swift 기초문법 - Closure  (0) 2022.09.14
Swift 기초문법 - Generic  (0) 2022.09.14
swift 기초문법 - enum  (0) 2022.09.12
swift 기초문법 - 콜렉션과 foreach  (0) 2022.09.12
swift 기초문법 - 01. 조건문  (0) 2022.09.12