열거형 UITableViewCell.CellStyle

enum을 사용하는 프로그래밍 언어
| 언어 | 특성 | 예시 |
| Swift | 연관값, 메서드 포함 가능 | enum Direction { case north } |
| C/C++ | 정수 기반, 기본적 | enum Color { RED, GREEN } |
| Java | 클래스형 enum, 필드/메서드 포함 가능 | enum Day { MONDAY, TUESDAY } |
| Python | enum 모듈 이용 | class Direction(Enum): ... |
| Kotlin | 강력한 enum, 메서드 포함 가능 | enum class Direction { ... } |
열거형 정의
enum Compass {
case North
case South
case East
case West
}
//var x : Compass // Compass형 인스턴스 x
print(Compass.North) // North
var x = Compass.West
print(type(of:x)) // Compass
x = .East
print(x) // East
열거형 멤버별 기능 정의
enum Compass {
case North
case South
case East
case West
}
var direction : Compass
direction = .South
switch direction { //switch의 비교값이 열거형 Compass
case .North: //direction이 .North이면 "북" 출력
print("북")
case .South:
print("남")
case .East:
print("동")
case .West:
print("서") //모든 열거형 case를 포함하면 default 없어도 됨
}
열거형 멤버에는 메서드도 가능
enum Week {
case Mon,Tue,Wed,Thur,Fri,Sat,Sun
func printWeek() { //메서드도 가능
switch self {
case .Mon, .Tue, .Wed, .Thur, .Fri:
print("주중")
case .Sat, .Sun:
print("주말") //출력결과 : 주말
}
}
}
Week.Sun.printWeek() //??
열거형의 rawValue
enum Color: Int { //원시값(rawValue) 지정
case red
case green = 2
case blue
}
print(Color.red) //red
print(Color.blue) //blue
print(Color.red.rawValue) //0
print(Color.blue.rawValue) //3
String형 값을 갖는 열거형의 rawValue
enum Week: String {
case Monday = "월"
case Tuesday = "화"
case Wednesday = "수"
case Thursday = "목"
case Friday = "금"
case Saturday //값이 지정되지 않으면 case 이름이 할당됨
case Sunday // = "Sunday"
}
print(Week.Monday) //Monday
print(Week.Monday.rawValue) //월
print(Week.Sunday) //Sunday
print(Week.Sunday.rawValue) //Sunday
연관 값(associated value)을 갖는 enum
enum Date {
case intDate(Int,Int,Int) //(int,Int,Int)형 연관값을 갖는 intDate
case stringDate(String) //String형 연관값을 값는 stringDate
}
var todayDate = Date.intDate(2025,4,30)
todayDate = Date.stringDate("2025년 5월 20일") //주석처리하면? 2025년 4월 30일
switch todayDate {
case .intDate(let year, let month, let day):
print("\(year)년 \(month)월 \(day)일")
case .stringDate(let date):
print(date) //2025년 5월 20일
}
옵셔널은 연관 값(associated value)을 갖는 enum
let age: Int? = 30 //Optional(30)
switch age {
case .none: // nil인 경우
print("나이 정보가 없습니다.")
case .some(let a) where a < 20:
print("\(a)살 미성년자입니다")
case .some(let a) where a < 71:
print("\(a)살 성인입니다")
default:
print("경로우대입니다")
} //30살 성인입니다.
var x : Int? = 20 //.some(20)
var y : Int? = Optional.some(10)
var z : Int? = Optional.none
var x1 : Optional<Int> = 30
print(x, y, z, x1) //Optional(20) Optional(10) nil Optional(30)
iOS 개발할 때 열거형 사용
네트워크 요청 상태 관리용 열거형
enum NetworkState {
case idle // 요청 대기 상태
case loading // 요청 중
case success(data: Data) // 요청 성공, 연관값으로 데이터 포함
case failure(error: Error) // 요청 실패, 연관값으로 에러 포함
}
사용 예시
func handleNetworkState(_ state: NetworkState) {
switch state {
case .idle:
print("대기 상태입니다.")
case .loading:
print("로딩 중입니다.")
case .success(let data):
print("성공! 데이터 크기: \(data.count) 바이트")
case .failure(let error):
print("실패: \(error.localizedDescription)")
}
}
- NetworkState 열거형은 네트워크 요청의 여러 상태를 표현
- .success와 .failure 케이스는 **연관값(Associated Values)**을 가지고 있어, 성공 시 데이터를, 실패 시 에러 정보를 함께 저장할 수 있음
- switch 문을 사용해 상태별로 적절한 처리를 할 수 있음
- 이렇게 하면 상태 관리가 명확해지고, 코드도 안전하고 가독성이 좋아짐
구조체

swift에서 구조체를 사용할 때와 클래스를 사용할 때
1. 구조체를 사용하는 경우
- 값 타입(Value Type): 구조체는 값을 복사해서 전달합니다. 따라서 복사본이 독립적이며, 원본에 영향을 주지 않음
- 불변성 유지가 중요할 때: 값이 변경되면 안 되거나, 상태가 독립적으로 유지되어야 할 때 적합함
- 상태가 가볍고, 단순한 데이터 모델: 좌표, 크기, 색상, 설정값 등 간단한 데이터 표현에 적합함
- 상속이 필요 없을 때: 구조체는 상속을 지원하지 않음
- 스레드 안전성: 값 복사 방식이라 멀티스레드 환경에서 안전함
struct Point {
var x: Int
var y: Int
}
var p1 = Point(x: 0, y: 0)
var p2 = p1
p2.x = 10
print(p1.x) // 0, p2.x는 10으로 독립적임
2. 클래스를 사용하는 경우
- 참조 타입(Reference Type): 클래스는 참조를 전달합니다. 즉, 여러 변수가 같은 인스턴스를 가리킬 수 있음
- 상태 공유가 필요할 때: 객체를 여러 곳에서 공유하며 상태가 변하면 모두에게 영향을 줘야 할 때 적합함
- 상속이 필요할 때: 클래스는 상속과 다형성(polymorphism)을 지원함
- 메모리 관리: ARC(자동 참조 카운트)를 통해 메모리를 관리함
- 복잡한 객체 관리: UI 컴포넌트, 네트워크 매니저 등 복잡한 동작과 상태를 가진 객체에 적합함
class Person {
var name: String
init(name: String) {
self.name = name
}
}
var person1 = Person(name: "Alice")
var person2 = person1
person2.name = "Bob"
print(person1.name) // Bob, 참조가 공유됨
요약
| 특징 | 구조체 (Struct) | 클래스 (Class) |
| 타입 | 값 타입 | 참조 타입 |
| 복사 방식 | 값 복사, 독립적 | 참조 전달, 공유 |
| 상속 | 불가 | 가능 |
| 사용 용도 | 간단한 데이터 모델, 불변성 유지 | 복잡한 상태 관리, 상속 필요시 |
| 멀티스레드 안전성 | 상대적으로 안전 | 주의 필요 |
클래스 내에 구조체
struct Resolution {
var width = 1024
var height = 768
}
class VideoMode {
var resolution = Resolution()
var frameRate = 0.0
}
let myVideo = VideoMode()
print(myVideo.resolution.width) //1024
class가 struct보다 더 갖는 특징

클래스/구조체 정의하기

구조체는 값 타입(value type) 클래스는 참조 타입(reference type)
struct Human {
var age : Int = 1
}
var kim = Human()
var lee = kim //값 타입
print(kim.age, lee.age)
lee.age = 20
print(kim.age, lee.age)
kim.age = 30
print(kim.age, lee.age)
var x = 1
var y = x
print(x,y)
x = 2
print(x,y)
y = 3
print(x,y)
//값 타입은 복사할 때 새로운 데이터가 하나 더 생김
class Human {
var age : Int = 1
}
var kim = Human()
var lee = kim //참조 타입
print(kim.age, lee.age)
lee.age = 20
print(kim.age, lee.age)
kim.age = 30
print(kim.age, lee.age)
//참조 타입은 복사할 때 주소를 복사해서
//한 데이터의 reference가 2개 생김
프로그래밍 언어에서 value type과 reference type을 비교
1. 값 타입(value type)
- 특징: 변수를 할당하거나 함수에 전달할 때, 실제 데이터가 복사되어 전달
- 복사본이 독립적이기 때문에 한 변수의 값을 변경해도 다른 변수에 영향을 미치지 않음
- 주로 기본 데이터 타입(숫자, 불리언, 구조체 등)이 값 타입으로 구현
struct Point {
var x: Int
var y: Int
}
var p1 = Point(x: 0, y: 0)
var p2 = p1 // p1이 p2에 복사됨 (값 복사)
p2.x = 10
print(p1.x) // 0, p1은 변하지 않음
print(p2.x) // 10, p2만 변경됨
2. 참조 타입 (Reference Type)
- 특징: 변수를 할당하거나 함수에 전달할 때, 데이터가 저장된 메모리 주소(참조)가 전달
- 여러 변수가 같은 객체를 참조하기 때문에, 한 변수를 통해 객체를 변경하면 모든 참조가 영향을 받음
- 주로 클래스 객체가 참조 타입
class Person {
var name: String
init(name: String) {
self.name = name
}
}
var person1 = Person(name: "Alice")
var person2 = person1 // person1과 person2가 같은 객체를 참조
person2.name = "Bob"
print(person1.name) // Bob, person1도 변경된 값 반영
print(person2.name) // Bob
차이점 요약
| 구분 | 값 타입(Value Type) | 참조 타입(Reference Type) |
| 복사 방식 | 데이터 자체 복사 | 데이터 주소(참조) 복사 |
| 변수 간 독립성 | 독립적 (변경 시 서로 영향 없음) | 공유 (변경 시 모두 영향 받음) |
| 메모리 위치 | 스택(stack)에 저장되는 경우 많음 | 힙(heap)에 저장되고 참조 전달 |
| 대표 타입 | Int, Float, Bool, Struct, Enum | Class, Closure |
언제 어떤 타입을 써야 할까?
- 값 타입은 데이터가 작고 단순하며, 복사해도 문제가 없을 때 적합
- 참조 타입은 여러 곳에서 같은 객체를 공유하고 상태를 관리해야 할 때 적합

class Human {
var age: Int = 1 // Human 클래스의 프로퍼티 age를 초기값 1로 선언
}
var kim = Human() // Human 인스턴스 하나 생성, kim이 참조(주소)를 가짐
var lee = kim // lee도 kim이 가리키는 같은 인스턴스(참조)를 가리킴
print(kim.age, lee.age) // 출력: 1 1
// kim과 lee가 같은 인스턴스를 참조하므로 age 값이 같음
lee.age = 20
// lee를 통해 인스턴스의 age 값을 20으로 변경
// kim도 같은 인스턴스를 참조하므로 kim.age도 20으로 바뀜
print(kim.age, lee.age) // 출력: 20 20
// 두 변수 모두 같은 인스턴스를 가리키기 때문에 변경 사항이 반영됨
kim.age = 30
// 이번엔 kim을 통해 age 값을 30으로 변경
print(kim.age, lee.age) // 출력: 30 30
// 역시 같은 인스턴스를 참조하므로 lee.age도 30으로 변경됨
// 정리: 참조 타입은 변수에 할당할 때 '인스턴스의 주소(참조)'를 복사함
// 따라서 kim과 lee는 같은 인스턴스를 가리키는 '참조' 2개가 존재
// 한쪽에서 값을 변경하면, 다른 쪽에서도 변경된 값이 보임
구조체는 값 타입(value type) 클래스는 참조 타입(reference type)
struct Resolution {
var width = 0
var height = 0
}
class VideoMode {
var resolution = Resolution()
var frameRate = 0
var name: String?
}
var hd = Resolution(width: 1920, height: 1080)
//자동 Memberwise Initializer
var highDef = hd
//구조체는 값타입(value type)
print(hd.width, highDef.width)
hd.width = 1024
print(hd.width, highDef.width)
var xMonitor = VideoMode()
xMonitor.resolution = hd
xMonitor.name = "LG"
xMonitor.frameRate = 30
print(xMonitor.frameRate)
var yMonitor = xMonitor
//클래스는 참조타입(reference type)
yMonitor.frameRate = 25
print(yMonitor.frameRate)
print(xMonitor.frameRate)
swift에서 class, struct, enum, protocol, extension 사용
| 개념 | 특징 | 언제 사용하는가? | 예시 용도 |
| Class | 참조 타입, 상속 가능 | 상태 공유, 상속, 복잡한 객체 | 뷰 컨트롤러, 네트워크 매니저 |
| Struct | 값 타입, 상속 불가 | 가벼운 데이터, 불변성, 복사 필요 | 좌표, 색상, 설정값 |
| Enum | 상태 표현, 연관값 가능 | 명확한 상태, 옵션, 이벤트 관리 | 네트워크 상태, 앱 상태 |
| Protocol | 인터페이스 정의, 다형성 지원 | 공통 기능 강제, 타입 추상화 | 드라이브 가능한 객체, 데이터 소스 |
| Extension | 기존 타입 기능 확장 | 기존 타입에 기능 추가, 코드 분리 | 유틸리티 함수, 프로토콜 준수 분리 |
class, struct, enum, protocol, extension 모두 들어간 iOS 소스
import Foundation
// MARK: - Enum (사용자 상태)
enum UserStatus {
case active
case inactive
case banned(reason: String) // 연관값 포함
func description() -> String {
switch self {
case .active:
return "활성 상태"
case .inactive:
return "비활성 상태"
case .banned(let reason):
return "정지됨: \(reason)"
}
}
}
// MARK: - Protocol (사용자 정보 표시)
protocol UserDisplayable {
func displayInfo() -> String
}
// MARK: - Struct (주소 정보, 값 타입)
struct Address {
var city: String
var street: String
}
// MARK: - Class (사용자 클래스, 참조 타입)
class User: UserDisplayable {
var name: String
var age: Int
var status: UserStatus
var address: Address
init(name: String, age: Int, status: UserStatus, address: Address) {
self.name = name
self.age = age
self.status = status
self.address = address
}
func displayInfo() -> String {
return "이름: \(name), 나이: \(age), 상태: \(status.description()), 주소: \(address.city) \(address.street)"
}
}
// MARK: - Extension (User 클래스에 기능 추가)
extension User {
func isAdult() -> Bool {
return age >= 18
}
func updateAddress(city: String, street: String) {
address = Address(city: city, street: street)
}
}
// MARK: - 사용 예시
let address = Address(city: "Seoul", street: "Gangnam-daero 123")
let user = User(name: "홍길동", age: 25, status: .active, address: address)
print(user.displayInfo()) // 이름: 홍길동, 나이: 25, 상태: 활성 상태, 주소: Seoul Gangnam-daero 123
print("성인 여부: \(user.isAdult() ? "성인" : "미성년자")") // 성인 여부: 성인
user.updateAddress(city: "Busan", street: "Haeundae-ro 456")
print(user.displayInfo()) // 변경된 주소 반영 출력
iOS 강의 자료 참고했습니다
'iOS프로그래밍 실무' 카테고리의 다른 글
| [iOS프로그래밍 실무] 12주차 (0) | 2025.05.28 |
|---|---|
| [iOS프로그래밍 실무] 11주차 (0) | 2025.05.15 |
| [iOS프로그래밍 실무] 10주차 (1) | 2025.05.08 |
| [iOS프로그래밍 실무] 9주차 (1) | 2025.05.07 |
| [iOS프로그래밍 실무] 6주차 (0) | 2025.04.10 |
| [iOS프로그래밍 실무] 5주차 (0) | 2025.04.03 |
| [iOS프로그래밍 실무] 4주차 (0) | 2025.03.27 |
| [iOS프로그래밍 실무] 3주차 (0) | 2025.03.20 |