카테고리 없음

iOS 프로그래밍 실무 7주차

sw0913 2025. 4. 16. 16:09

enum을 지원하는 프로그래밍 언어

  • 자바
  • 파이썬
  • C
  • C#
  • 파스칼
  • 에이다

열거형은 처음에만 열거형의 이름을 작성해주고 그 뒤에는 생략하여 사용할 수 있어요

Swift에서 열거형(Enumeration)은 관련된 값들의 그룹을 공통된 타입으로 정의하는 것

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

모든 열거형 case를 포함하면 default 없어도 됩니다

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

var direction : Compass
direction = .North

switch direction { //switch의 비교값이 열거형 Compass
case .North: //direction이 .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:
            print("주중")
        case .Sat, .Sun:
            print("주말")
        }
    }
}

Week.Sun.printWeek()

열거형의 rawValue

  • 열거형은 0부터 시작해요
  • enum Color: Int { //원시값(rawValue) 지정 case red case green = 2 case blue } print(Color.red) //red print(Color.blue) print(Color.red.rawValue) //0 print(Color.blue.rawValue)

String형 값을 갖는 열거형의 rawValue

  • rawValue를 String형으로 지정
  • 값이 지정되지 않으면 case 이름이 할당돼요
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.Saturday) //Saturday
print(Week.Saturday.rawValue) //Saturday
print(Week.Sunday) //Sunday
print(Week.Sunday.rawValue) //Sunday

연관 값을 갖는 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일") //주석처리하면?

switch todayDate {
case .intDate(let year, let month, let day):
    print("\(year)년 \(month)월 \(day)일")
case .stringDate(let date):
    print(date)
}
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("경로우대입니다")
}


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)

구조체

구조체 : Memberwise Initializer 자동 생성

struct Resolution { //구조체 정의
    var width = 1024 //프로퍼티
    var height = 768
}

let myComputer = Resolution() //인스턴스 생성
print(myComputer.width) //프로퍼티 접근

struct Resolution { //구조체 정의
    var width : Int //프로퍼티 초기값이 없어요!!
    var height : Int
} //init()메서드 없어요, 그런데!

let myComputer2 = Resolution(width:1920, height:1080) //Memberwise Initializer
print(myComputer2.width)

클래스 내에 구조체

struct Resolution {
    var width = 1024
    var height = 768
}

class VideoMode {
    var resolution = Resolution()
    var frameRate = 0.0
}

let myVideo = VideoMode()
print(myVideo.resolution.width)

클래스 (Class)

  • 참조 타입 (Reference Type): 인스턴스 전달 시 참조가 전달되어, 여러 변수가 동일 인스턴스를 가리킬 수 있습니다. 한 변수에서 변경하면 다른 변수에도 반영됩니다.
  • 상속 가능: 다른 클래스로부터 상속을 통해 기능 확장 및 수정이 가능합니다.
  • ARC로 메모리 관리: 더 이상 참조되지 않을 때 자동으로 메모리에서 해제됩니다.
  • deinit 메서드: 인스턴스 해제 직전 호출되어 정리 작업을 수행합니다.

구조체 (Struct)

  • 값 타입 (Value Type): 인스턴스 전달 시 복사본이 생성되어 각 변수는 독립적인 인스턴스를 가집니다. 한 변수 변경이 다른 변수에 영향을 주지 않습니다.
  • 상속 불가능: 다른 타입으로부터 상속받을 수 없습니다.
  • 스택에 저장: 일반적으로 스택에 저장되어 메모리 할당 및 해제가 빠릅니다.
  • 기본 Initializer 제공: 생성자를 구현하지 않아도 기본 Initializer 사용이 가능합니다.

선택 기준

다음과 같은 경우에는 구조체를 사용하는 것이 좋습니다:

  • 데이터 캡슐화: 연관된 간단한 값의 집합을 캡슐화할 때.
  • 값 복사: 값을 참조하는 것보다 복사하는 것이 합당할 때.
  • 값 타입 프로퍼티: 프로퍼티가 값 타입이며, 참조보다 복사가 합당할 때.
  • 상속 불필요: 상속이 필요 없을 때.

Objective-C와의 상호 운용성이 필요하거나 참조 타입의 특징이 필요한 경우에는 클래스를 사용해야 합니다.

클래스/구조체 정의하기

클래스 정의하기

  • class 이름 { ... } 형태로 정의합니다.

구조체 정의하기

  • struct 이름 { ... } 형태로 정의합니다.

타입 이름 작성 규칙

  • Upper Camel Case를 사용합니다.
    • 대문자로 시작합니다.

클래스/구조체 안의 프로퍼티나 메서드 작성 규칙

  • lower Camel Case를 사용합니다.
    • 소문자로 시작합니다.

예시 코드

struct Resolution {
var width = 0
var height = 0
}

class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
}

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

struct Human {
    var age: Int = 1
}

var kim = Human()
var lee = kim // 값 타입이므로 복사본이 생성됨

print(kim.age, lee.age) // 1 1

lee.age = 20
print(kim.age, lee.age) // 1 20

kim.age = 30
print(kim.age, lee.age) // 30 20

var x = 1
var y = x

print(x, y) // 1 1

x = 2
print(x, y) // 2 1

y = 3
print(x, y) // 2 3

class Human {
    var age: Int = 1
}

var kim = Human()
var lee = kim // 참조 타입이므로 같은 인스턴스를 가리킴

print(kim.age, lee.age) // 1 1

lee.age = 20
print(kim.age, lee.age) // 20 20

kim.age = 30
print(kim.age, lee.age) // 30 30

참조 타입(Reference Type)의 개념

참조 타입은 변수나 상수에 인스턴스를 할당하거나 함수에 전달할 때 메모리 주소(참조)를 복사하는 타입입니다.
이때 여러 변수/상수가 동일한 인스턴스를 가리키게 되며, 한 쪽에서 값을 변경하면 다른 쪽에도 반영됩니다.


참조 타입의 특징

1. 동일 인스턴스 공유

  • 클래스(class)로 생성된 인스턴스는 힙(Heap) 메모리에 저장됩니다.
  • 변수는 스택(Stack) 메모리에 인스턴스의 주소를 저장합니다.
  • 변수 간 할당 시 주소만 복사되므로, 모든 변수가 같은 인스턴스를 참조합니다.

2. 상속 가능

  • 다른 클래스로부터 상속받아 기능을 확장하거나 재정의할 수 있습니다.

3. ARC (Automatic Reference Counting)

  • 참조 횟수를 자동으로 관리하여 메모리 누수를 방지합니다.
  • 인스턴스가 더 이상 참조되지 않으면 메모리에서 해제됩니다.

4. deinit 메서드

  • 인스턴스가 메모리에서 해제되기 직전에 호출됩니다.
    (예: 리소스 정리, 네트워크 연결 종료)


메모리 구조

메모리 영역 저장 내용 특징
힙(Heap) 클래스 인스턴스 동적 할당, 참조 카운팅(ARC) 관리
스택(Stack) 변수/상수의 주소(참조값) 빠른 할당/해제, 크기 고정
  • kimlee스택에 저장된 주소로 의 동일한 인스턴스를 가리킵니다.
  • 한 변수의 값 변경이 다른 변수에 영향을 줍니다.

값 타입(Value Type) vs 참조 타입(Reference Type)

구분 값 타입 참조 타입
할당 방식 값 복사 주소 복사
메모리 영역 스택
독립성 복사 후 독립적 복사 후 동일 인스턴스 참조
사용 예시 struct, enum, 기본 타입(Int 등) class, closure

참조 타입 사용 시나리오

  1. 상속이 필요한 경우
    (예: UIViewController, UITableViewCell 서브클래스)
  2. 공유된 상태 관리가 필요한 경우
    (예: 싱글턴 패턴, 네트워크 매니저)
  3. Objective-C와의 호환성이 필요한 경우
    (예: UIKit, Core Data)
  4. 인스턴스 식별이 필요한 경우
    (예: === 연산자로 동일성 비교)

핵심 정리:
참조 타입은 동일한 데이터를 공유해야 할 때 사용하며,
값 타입은 독립적인 복사본이 필요할 때 사용합니다.

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

프로그래밍 언어에서 Value TypeReference Type의 차이

1. 기본 개념

Value Type (값 타입)

  • 값 자체를 변수에 저장합니다.
  • 독립적인 복사본이 생성됩니다.
    → 한 인스턴스를 수정해도 다른 인스턴스에 영향을 주지 않습니다.
  • 스택(Stack) 메모리에 저장됩니다.
    → 빠른 할당/해제가 가능합니다.

Reference Type (참조 타입)

  • 메모리 주소(참조)를 변수에 저장합니다.
    → 실제 데이터는 힙(Heap) 메모리에 저장됩니다.
  • 동일한 인스턴스를 공유합니다.
    → 한 인스턴스를 수정하면 모든 참조가 변경됩니다.

2. 차이점 비교표

구분 Value Type Reference Type
저장 위치 스택(Stack) 힙(Heap)
할당 방식 값 복사 주소 복사
독립성 복사 후 독립적 복사 후 동일 인스턴스 참조
메모리 관리 스택에서 자동 해제 가비지 컬렉션 또는 ARC 관리
사용 예시 Int, Double, Struct (Swift) Class (Swift), 객체 (Java)
상속 가능 여부 불가능 가능

3. 동작 예시

Value Type (예: Swift struct)

struct Point {
var x: Int
var y: Int
}

var a = Point(x: 1, y: 2)
var b = a // 값 복사
b.x = 3

print(a.x) // 1 (a는 변경되지 않음)
print(b.x) // 3

Reference Type (예: Swift class)

class Person {
var name: String
init(name: String) { self.name = name }
}

var personA = Person(name: "Alice")
var personB = personA // 주소 복사
personB.name = "Bob"

print(personA.name) // "Bob" (같은 인스턴스 참조)
print(personB.name) // "Bob"

4. 언제 사용할까?

✔️ Value Type을 사용하는 경우

  • 독립적인 복사본이 필요할 때 (예: 좌표, 금액).
  • 스레드 안전성이 요구될 때.
  • 작은 데이터를 빠르게 처리해야 할 때.

✔️ Reference Type을 사용하는 경우

  • 공유된 상태를 관리해야 할 때 (예: 싱글턴).
  • 상속이 필요한 경우.
  • 대용량 데이터를 효율적으로 처리해야 할 때.

5. 주요 언어별 예시

언어 Value Type 예시 Reference Type 예시
Swift Int, Struct, Enum, Tuple Class, Closure
C# int, struct class, interface, delegate
Java int, double (기본형) String, 객체
Python 불변 타입 (int, str, tuple) 가변 타입 (list, dict, 객체)

6. 메모리 관리 차이

  • Value Type:
    스택에 저장되어 함수 종료 시 자동으로 해제됩니다.
    빠르고 안전합니다.
  • Reference Type:
    힙에 저장되며, 참조 카운팅(ARC) 또는 가비지 컬렉션으로 관리됩니다.
    유연하지만 오버헤드가 발생할 수 있습니다.

핵심 요약:

  • 값 타입 = 독립적인 복사본 생성 (예: 돈 복사)
  • 참조 타입 = 원본 데이터 공유 (예: 공유 문서 편집)

extension Double {
    var squared: Double {
        return self * self
    }
}

// 이제 Double형 인스턴스에서 squared 프로퍼티를 사용할 수 있습니다.
let myValue: Double = 3.5
print(myValue.squared)    // 12.25
print(3.5.squared)        // 12.25 (Double 값에도 바로 사용 가능)
print(myValue.isZero)     // false (Double의 내장 프로퍼티)

 

출처 - Smile Han