일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- swift
- swift ac 문제풀이
- MVVM
- swift codility
- 백준 2xn 타일링
- ac 투포인터
- 연속된 부분 수열의 합 투포인터
- swift dfs
- swift 연속된 부분 수열의 합
- ac 구현 풀이
- 백준 2xn 타일링 풀이
- swift 2xn 타일링 풀이
- swift ac 풀이
- iOS Charts
- swift gRPC
- 연속된 부분 수열의 합 swift
- swift 9095 풀이
- swift 2xn 타일링
- 123 더하기 풀이
- rxswift
- 1 2 3 더하기 풀이
- swift 2xn 타일링 백준
- ac swift 풀이
- swift ac
- ios
- swift 백준 9095
- swift algorithm
- swift 연속된 부분 수열의 합 풀이
- swift 프로그래머스
- swift 알고리즘
- Today
- Total
boraBong
[Swift] 구조체와 클래스 본문
[구조체와 클래스]
💡 구조체와 클래스가 뭔가요?
- 프로그래머가 데이터를 용도에 맞게 묶어 표현하고자 할 때
- 프로퍼티와 메서드를 사용하여 구조화된 데이터와 기능을 가질 수 있는 하나의 새로운 사용자 정의 데이터 타입을 만들어주는 것
- 스위프트에서는 구조체와 클래스의 모습과 문법이 매우 흡사하다.
💡 구조체와 클래스의 차이점?
- ✅ 구조체의 인스턴스 : 값 타입
- ✅ 클래스의 인스턴스 : 참조 타입
⇒ 조금 뒤에 덧붙여 설명
구조체
🏷️ 구조체는 “Struct” 키워드로 정의 구조체를 정의한다는 것은 새로운 타입을 생성하는 것과 마찬가지
→ 기본 타입 이름 (Int, String, Bool 등) 처럼 대문자 카멜케이스를 사용하여 명명 → → 구조체 내의 프로퍼티와 메서드는 소문자 카멜케이스를 사용하여 명명
struct 구조체 이름 {
// 프로퍼티와 메서드들
}
struct BasicInformation {
var name: String
var age: Int
}
→ 이렇게 구조체 정의 후 인스턴스를 생성하고 초기화하고자 할 때는 기본적으로 생성되는 멤버와이즈 이니셜라이저를 사용
클래스
🏷️ 클래스는 “Class” 키워드로 정의 클래스를 정의한다는 것은 새로운 타입을 생성하는 것과 마찬가지
→ 기본 타입 이름 (Int, String, Bool 등) 처럼 대문자 카멜케이스를 사용하여 명명 → → 클래스 내의 프로퍼티와 메서드는 소문자 카멜케이스를 사용하여 명명
class 클래스 이름 {
// 프로퍼트와 메서드들
}
// MARK: 상속의 경우
class 클래스 이름: 부모클래스 이름 {
// 프로퍼트와 메서드들
}
class Person {
var weight: Float = 0.0
var height: Float = 0.0
}
클래스를 정의한 후 인스턴스를 생성하고 초기화하고자할 때는 기본적인 이니셜라이저를 사용한다.
인스턴스가 생성되고 초기화된 후 프로퍼티 값에 접근하고 싶다면 마침표 (.)를 사용하면 된다.
[ 클래스 인스턴스의 소멸 ]
- 클래스 인스턴스는 참조 타입이므로 더는 참조할 필요가 없을 때 메모리에서 해제된다.
- 이 과정을 “소멸” 이라고 함
- 소멸되기 직전 deinit라는 메서드가 호출됨
class Person {
var height: Float = 0.0
var weight: Float = 0.0
deinit {
print("Person 클래스의 인스턴스가 소멸됩니다.")
}
}
var boraBong: Person? = Person()
boraBong = nil // Person 클래스의 인스턴스가 소멸됩니다.
deinit 메서드에는 인스턴스가 메모리에서 해제되기 직전에 처리할 코드를 넣어준다.
💡 구조체와 클래스의 차이
[공통점]
- 값을 저장하기 위해 프로퍼티를 저장할 수 있음
- 기능 실행을 위해 메서드를 정의할 수 있음
- 서브스크립트 문법을 통해 구조체 또는 클래스가 갖는 값(프로퍼티)에 접근하도록 서브스크립트를 정의할 수 있음
- 초기화될 때의 상태를 지정하기 위해 이니셜라이저를 정의할 수 있음
- 초기구현과 더불어 새로운 기능 추가를 위해 익스텐션을 통해 확장할 수 있음
- 특정 기능을 실행하기 위해 특정 프로토콜을 준수할 수 있음
[차이점]
- 구조체는 상속 불가
- 타입캐스팅은 클래스의 인스턴스에만 허용됨
- 디이니셜라이저는 클래스의 인스턴스에만 활용할 수 있음
- 참조 횟수 계산은 클래스의 인스턴스에만 적용됨
💡 그래서, 값 타입과 참조 타입이란?
값 타입과 참조 타입의 가장 큰 차이 ➡️ ‘무엇이 전달되는가'
스위프트의 데이터 타입과 열거형은 ⇒ 모두 값 타입
C언어, Objective-C의 포인터와 유사한 개념 ⇒ 참조 타입
🏷️ 어떤 함수의 전달인자로 값 타입의 값을 넘긴다면 전달될 값이 복사되어 전달된다. 그러나, 참조 타입이 전달인자로 전달될 때는 값을 복사하지 않고 참조(주소)가 전달된다. 참조라는 것은 C, C++, Objective-C등의 언어에서 사용되는 포인터와 매우 유사한 개념이지만, swift에서는 참조라는 것을 표현하기 위해 *를 사용하지는 않는다!
⭐️ 구조체와는 다르게 클래스의 인스턴스는 “참조타입" 이므로 클래스의 인스턴스를 상수 let으로 선언해도 내부 프로퍼티 값을 변경할 수 있음 !! ⭐️
[ 코드로 알아보기 ]
struct BasicInformation {
let name: String
var age: Int
}
var boraBongInfo: BasicInformation = BasicInformation(name: "보라봉", age: 100)
boraBongInfo.age = 101
// boraBongInfo의 값을 복사하여 할당
var friendInfo: BasicInformation = boraBongInfo
print("borabong's age: \\(boraBongInfo.age)") // 101
print("friend's age: \\(friendInfo.age)") // 101
friendInfo.age = 102
print("borabong's age: \\(boraBongInfo.age)") // 101
print("friend's age: \\(friendInfo.age)") // 102 - friendInfo는 boraBongInfo의 값을 복사하여 갖고왔기 때문에 별개의 값을 가짐
class Person {
var height: Float = 0.0
var weight: Float = 0.0
}
var boraBong = Person()
var friend = boraBong
print("boraBong's height: \\(boraBong.height)") // 0.0
print("friend height: \\(friend.height)") // 0.0
friend.height = 161.5
print("boraBong's height: \\(boraBong.height)") // 161.5 - friend는 boraBong을 참조하기 때문에 값이 변동됨
🏷️ 값 타입의 데이터를 함수의 전달인자로 전달하면 메모리에 전달인자를 위한 인스턴스가 새로 생성됩니다. 그리고 생성된 새 인스턴스에는 전달하려는 값이 복사되어 들어가게 됩니다.
반면에, 참조 타입의 데이터는 전달인자로 전달할 때 기존 인스턴스의 참조를 전달하기 때문에 새로운 인스턴스가 아닌 기존의 인스턴스 참조를 전달합니다.
출처: Swift 프로그래밍 3판 (yagom) 책을 참고하였습니다.
'iOS > Swift' 카테고리의 다른 글
[Swift] Regex, 정규표현식 사용하기 (0) | 2023.02.22 |
---|---|
[Swift] Swift 고차함수 문법 - Map, Filter, Reduce (0) | 2023.01.08 |
[Swift] 함수형 프로그래밍이란? (0) | 2020.12.08 |