iOS 실무 7주차

CDH·2025년 4월 16일

열거형(enum)

열거형 UITableViewCell.CellStyle

https://developer.apple.com/documentation/uikit/uitableviewcell/cellstyle

AI 질문 : enum을 지원하는 프로그래밍 언어를 모두 다 알려줘



열거형 정의

enum Compass { // 열거형의 자료형
    case North
    case South
    case East
    case West
    // case North, South, East,  West // 콤마로 나열 가능
}
//var x : Compass // Compass형 인스턴스 x
print(Compass.North) // North
var x = Compass.West // .(점)을 사용하여 호출
print(type(of:x)) // Compass
x = .East // 열거형 이름 생략 가능 (앞에서 값을 대입함)
print(x) // East
  • 열거형은 처음에 값을 대입하면, 그 이후로는 생략 가능하다
  • 열거형은 콤마로 case 문에서 정의(나열) 가능하다

열거형 멤버별 기능 정의

enum Compass {
    case North
    case South
    case East
    case West
}

var direction: Compass
direction = .North

switch direction {
case .North:
    print("북")
case .South:
    print("남")
case .East:
    print("동")
case .West:
    print("서")
}

결과


열거형 멤버에는 메서드도 가능

열거형은 함수도 정의 가능하다

enum Week {
    case Mon, Tue, Wed, Thur, Fri, Sat, Sun
    
    func printWeek() {
        switch self {
        case .Mon, .Tue, .Wed, .Thur, .Fri: // case를 콤마로 나열 가능
            print("주중")
        case .Sat, .Sun:
            print("주말")
        }
    }
}

Week.Sun.printWeek()

열거형의 rawValue

중간에 'green' 의 값을 2로 지정해서 'blue' 의 값이 그 다음 값인 3부터 시작됨

enum Color: Int {
    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 // Saturday
    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)
}

옵셔널은 연관 값(associated value)을 갖는 enum

  • .none과 .some은 내장 함수가 아니라, Swift에서 옵셔널(Optional) 열거형의 내부 케이스(case)
  • .some (값이 존재할 때의 경우)
  • .none (값이 없을 때. nil일 경우를 뜻함)

※ Swift의 열거형은 크게 단순 열거형과 연관 값이 있는 열거형 두 가지로 나눌 수 있다
단순 열거형은 값들이 고정되어 있고,
연관 값이 있는 열거형은 각 항목이 다양한 타입의 연관 값을 가질 수 있다

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살 성인입니다.

알고가기 (Optional 과 열거형)

  • Swift에서는 Optional도 그냥 열거형이다. 내부적으로 다음과 같이 정의되어 있다
enum Optional<Wrapped> {
    case some(Wrapped)
    case none
}


구조체(struct)

중요!
- 구조체/enum의 인스턴스는 값(value) 타입, 클래스의 인스턴스는 참조(reference) 타입
- 구조체는 상속 불가


(중요!) 구조체 : Memberwise Initializer 자동 생성

  • 구조체(struct)로 선언한다면 Memberwise Initializer 를 자동으로 만들어 주기 때문에 따로 선언할 필요가 없다.
  • 구조체의 이름은 보통 대문자로 시작
  • 괄호가 있다면 인스턴스 생성
    - struct 를 class로 변경하려면 initializer 를 따로 선언해줘야 한다

struct Resolution { // 구조체 정의
    var width = 1024 // 프로퍼티
    var height = 768
}
let myComputer = Resolution() // 인스턴스 생성 (괄호가 있다면)
print(myComputer.width) // 프로퍼티 접근

struct Resolution { // 구조체 정의, struct 대신 class로 선언한다면 에러 발생 (init이 없기 때문)
    var width: Int // 프로퍼티 초기값이 없어요!!
    var height: Int
} //init()메서드 없어요, 그런데!
let myComputer = Resolution(width: 1920, height: 1080) // Memberwise Initializer
print(myComputer.width)

클래스로 변경 시

class Resolution { // 구조체 정의, struct 대신 class로 선언한다면 에러 발생 (init이 없기 때문)
    var width: Int // 프로퍼티 초기값이 없어요!!
    var height: Int
    
    init(width:Int, height:Int) {
        self.width = width
        self.height = height
    }
} //init()메서드 없어요, 그런데!
let myComputer = Resolution(width: 1920, height: 1080) // Memberwise Initializer
print(myComputer.width)

참고용


클래스 내에 구조체

클래스 내에서 구조체에 접근하려면 .(점)을 이용하여 중첩된 구조체를 사용한다

Swift 기본 데이터 타입은 모두 구조체


클래스와 구조체 사용 기준 (AI 질문)

질문 : swift에서 클래스와 구조체를 어떻게 나눠서 사용해야 되는지 표로 만들어줘

언제 클래스를 사용해야 할까요?

  • 상속이 필요한 경우.
  • 참조 타입이 필요한 경우 (여러 인스턴스가 동일한 객체를 참조하고, 이를 수정해야 할 때).
  • 객체 간 데이터 공유가 필요한 경우 (객체 상태를 여러 부분에서 동시에 변경할 때).


    언제 구조체를 사용해야 할까요?
  • 값 타입이 필요할 때 (값을 복사하여 독립적인 상태를 유지해야 할 때).
  • 상태 변경이 필요 없는 경우 (값을 변경할 때마다 새로 복사해서 저장하는 방식이 유리할 때).
  • 간단한 데이터 모델을 다룰 때 (예: Point, Size와 같은 간단한 데이터 구조).

class가 struct보다 더 갖는 특징

( 공통점 보다는 차이점에 주목하기)


클래스/구조체 정의하기

class상속이 가능하다는 것이 가장 큰 특징이
swift에서는 부모와 자식 간에 형변환이 가능하다


클래스/구조체 정의하기


(중요!) 구조체는 값 타입(value type) 클래스는 참조 타입(reference type)

값 타입(value type)의 코드

참조 타입(reference type) 의 코드

값 타입(Value Type)은 데이터를 복사하여 독립적인 인스턴스를 생성하는 반면, 참조 타입(Reference Type)동일한 메모리 주소를 참조하여 여러 인스턴스가 같은 데이터를 공유한다.

  • class 와 struct 둘의 결과값이 다름

다른 예제


언제 클래스를 쓰고 언제 구조체를 쓰나?

  • 클래스는 참조타입, 구조체는 값 타입
    - 구조체는 간단한 데이터 값들을 한데 묶어서 사용하는 경우
    - 전체 덩어리 크기가 작은 경우, 복사를 통해 전달해도 좋은 경우 구조체
    - 멀티 쓰레드 환경이라면 구조체가 더 안전
    • 구조체는 상속할 필요가 없는 경우
      - 너비, 높이를 표현하는 기하학적 모양을 처리할 경우
      - 시작값, 증분, 길이 등으로 순열을 표현할 경우
      - 3차원 좌표 시스템의 각 좌표

extension

extension(확장)

  • 기존 클래스에 기능을 추가할 때 사용


class, sruct, enum, protocol, extension

  • AI 질문 : 스위프트에서 class, sruct, enum, protocol, extension 이 5가지가 언제 사용되는지 알려줘

클래스: 상태와 동작을 정의하고 상속이 필요한 경우 사용.

구조체: 값 타입으로 독립적인 데이터를 다루고, 상속 없이 간단한 데이터 구조를 표현할 때 사용

열거형: 연관된 값을 묶어 타입을 정의하고, 조건별 분기가 필요한 경우 사용.

프로토콜: 특정 동작을 요구하는 인터페이스로, 다형성을 구현할 때 사용.

확장: 기존 타입에 새로운 기능을 추가할 때 사용.

업로드중..

0개의 댓글