iOS

[iOS] 옵셔널 체이닝 Error_Handling Generic Array

챎 님 2025. 4. 9. 16:39
더보기

이 포스트는 한성현 교수님의 iOS 프로그래밍 실무 수업을 듣고 작성하였습니다.

오늘은 옵셔널 체이닝에 대해 먼저 예시를 들어 알아 보며, 작성을 시작해 보겠습니다.

 

✔️ 옵셔널 체이닝

JavaScript에서 객체나 배열의 특정 속성 또는 메서드에 접근할 때, 해당 값이 `null` 또는 `undefined`인지 확인하지 않고도 안전하게 접근할 수 있도록 도와주는 문법입니다. 옵셔널 체이닝 연산자는 `?.`로 표시됩니다.

쉽게 설명해 보자면, "만약 이 값이 존재하면 그 다음 속성에 접근하고, 

그렇지 않으면 에러를 내지 않고 `undefined`를 반환해!“라는 역할을 합니다.

 

이제 Swift 옵셔널 개념 실습 코드를 간단히 올리며, 설명해 보겠습니다.

일단 옵셔널은 값이 있을 수도 없을 수도 있는 타입입니다.

// 옵셔널 문자열 선언
var x: String? = "Hi" // "Hi"를 지운 후 nil 테스트도 가능

// print: 옵셔널과 강제 언래핑된 값 출력
print(x, x!) // x는 Optional("Hi"), x!는 "Hi"

// 옵셔널 바인딩 (안전하게 꺼내기)
if let a = x {
    print(a) // "Hi"
}

// 강제 언래핑 후 문자열 길이 확인
let b = x!.count
print(type(of: b), b) // Int 2

// 옵셔널 체이닝을 통한 문자열 길이 접근
let b1 = x?.count
print(type(of: b1), b1!, b1!) // Optional<Int> 2 2

// nil 병합 연산자 사용 (옵셔널 x가 nil이면 "" 반환)
let c = x ?? ""
print(c) // "Hi"

x! 나 b1! 처럼 강제 언래핑은 값이 nil 일 경우 앱이 죽을 수도 있으니, 옵셔널 바인딩 기능을 사용해 주는 것이 더 좋습니다.

가급적이면, if let 이나 guard let, ??, ?. 을 사용하여 안전하게 처리하는 것이 좋은 방법이 될 것 같습니다!

 

✔️ 옵셔널에서 ? 와 ! 의 차이

기호 의미 위험도 사용 예시
? 옵셔널 체이닝 안전함 x?.count
! 강제 언래핑 위험함 x! or x!.count

 

📌 ?: 옵셔널 체이닝

값이 존재하면 이어서 실행하고, 값이 없으면(nil) 아무 일도 안 하고 nil 반환합니다.

var x: String? = "Hi"
let length = x?.count // Optional(2)
print(length)         // Optional(2)

만약 xnil이면 lengthnil이 되며, 크래시 없이 안전하게 실행됩니다.

💡 사용 시기: 값이 있을 수도 없을 수도 있는 상황에서 안전하게 접근할 때.

 

📌 !: 강제 언래핑

옵셔널 값은 무조건 꺼내서 사용합니다.

값이 없으면(nil) 앱이 터집니다. ㅠㅠ

var x: String? = "Hi"
print(x!) // "Hi"

⚠️ 사용 시기: “여기선 무조건 값이 있어!“라고 확신할 때만 사용해야 합니다.

 

var x: String? = "Swift"

// 옵셔널 체이닝 (안전)
let safeCount = x?.count
print(safeCount) // Optional(5)

// 강제 언래핑 (확신이 있을 때만!)
let forcedCount = x!.count
print(forcedCount) // 5

// x가 nil일 경우
x = nil
print(x?.count) // nil (안전)
print(x!.count) // ❌ 크래시!

?는 “혹시 몰라 조심스럽게”,

!는 “무조건 있어, 질러!” 입니다.

 

Swift에서는 앱의 안정성이 중요하므로, !보다는

?, if let, guard let, ?? 등을 적극 활용하는 습관을 들이는 것이 좋습니다!

상황 추천 방식
값이 있을 수도 없을 수도 있다. ? (옵셔널 체이닝)
값이 있어야 하고, 확신이 있어야 한다. ! (강제 언래핑)
값이 있으면 사용, 없으면 대체 값 사용 ?? (nil 병합 연산자)

 

✔️ 오류 처리 Error Handling

✔️ throwing function

iOS 에서 가장 많이 사용되는 throwing function 을 포스팅해 보겠습니다.

 

 

🥇 1. Data(contentsOf:)

let data = try Data(contentsOf: url)

 

  • 로컬 파일 또는 원격 URL에서 데이터 불러올 때 사용
  • 오류 발생: 파일 없음, 인터넷 오류 등

 

🥈 2. JSONDecoder().decode(_:from:)

let user = try JSONDecoder().decode(User.self, from: data)

 

  • JSON 데이터를 Swift 모델로 디코딩할 때
  • 오류 발생: 타입 불일치, JSON 오류 등

정도 ChatGPT 를 통해 알아 보았습니다.

 

🥉 3. do-try-catch

이건 Swift에서 오류를 안전하게 처리하는 공식적인 방법입니다.

Swift는 오류가 발생할 수 있는 상황을 명시적으로 처리합니다. 그 중심에는 do-try-catch 문법이 있죠.

 

✅ 왜 필요한가요?

do {
    let result = try throwingFunction()
    // 성공 시 실행할 코드
} catch {
    // 오류 발생 시 실행할 코드
    print("오류 발생: \(error)")
}

Swift 함수 중 일부는 오류 발생 가능성이 있기 때문에 throws 키워드를 사용합니다.

이런 함수는 try 키워드와 함께 사용해야 하며, 오류를 직접 처리하거나 전달해야 합니다.

 

✔️ Generic

제네릭이란 코드에서 타입을 유연하게 지정할 수 있는 문법입니다. <> 이렇게 표기할 수 있습니다.

 

💡 왜 필요한가요?

같은 로직인데 타입만 다른 경우, 코드 중복 없이 하나의 함수나 타입으로 처리할 수 있습니다.

func swapInts(_ a: inout Int, _ b: inout Int) { ... }
func swapStrings(_ a: inout String, _ b: inout String) { ... }

이와 같은 중복되는 코드가 존재할 시에, 제네릭을 사용하게 된다면 밑과 같이 수정할 수 있습니다.

func swapValues<T>(_ a: inout T, _ b: inout T) {
    let temp = a
    a = b
    b = temp
}
  • 여기서 <T>타입을 추상화한 이름
  • T는 호출될 때 자동으로 타입이 결정됨

✔️ Collection Type - Array

Swift에서 가장 많이 사용되는 컬렉션 타입 중 하나는 바로 Array입니다. 동일한 타입의 값들을 순서대로 저장할 수 있는 자료구조죠.

Array는 여러 값을 하나의 변수에 담아두고, 인덱스를 통해 쉽게 접근할 수 있는 순서가 있는 리스트입니다.
let numbers = [1, 2, 3, 4, 5]​

 

  • 위 배열은 Int 타입의 값을 5개 저장하고 있습니다.
  • Swift의 Array는 **타입 안정성(Type-safe)**을 보장합니다.
// 타입 추론
let names = ["채림", "재현", "맥스"]

// 명시적 타입 선언
let scores: [Int] = [90, 85, 100]

// 빈 배열 만들기
var emptyArray1: [String] = []
var emptyArray2 = [String]()

이런 식으로 선언할 수 있습니다.

 

밑과 같은 코드로 배열 요소에 접근이 가능합니다.

let fruits = ["🍎", "🍌", "🍓"]

print(fruits[0]) // 🍎
print(fruits[1]) // 🍌
  • 인덱스는 0부터 시작합니다.
  • 존재하지 않는 인덱스에 접근하면 런타임 오류 발생!

즉, Array는 Swift에서 가장 자주 쓰는 기본 콜렉션! 타입 안전하고, 기능이 풍부하며, 고차 함수까지 완비한 현대적 자료구조입니다.

이전 발행글에 Array 를 다뤄 놓은 포스트도 있으니, 참고용으로 좋을 것 같습니다.

 

빈 배열을 받는 방법에 대해서도 설명해 보겠습니다.

두 가지로 나누어 볼 수 있습니다.

먼저, 타입을 명확히 아는 경우입니다.

var emptyArray: [Int] = []
  • Int 타입의 빈 배열입니다.
  • 초기화하면서 동시에 타입도 명시해주는 깔끔한 방식입니다.

두 번째로는 타입 추론이 가능한 경우입니다. 이는 보통 함수 내부나 context 가 명확할 때입니다.

var emptyArray = [String]()
  • Swift가 []의 타입을 추론할 수 있도록 생성자 형태로 작성합니다.

주의 사항으로는 상수 배열은 수정이 불가하다는 점입니다.

let constantArray: [String] = []
// constantArray.append("채림") // ❌ 에러 발생!

let상수이기 때문에, 생성 이후에 값을 추가하거나 삭제할 수 없습니다.

빈 배열에 값을 추가하고 싶다면 항상 변수 var 로 사용해야겠지요?

 

'iOS' 카테고리의 다른 글

[iOS] 클래스 열거형 구조체  (0) 2025.04.16
[iOS] Table View  (0) 2025.04.02
[iOS] 함수와 클래스 및 상속  (0) 2025.03.26
[iOS] 무드등 앱 개발 및 Swift 문법 복습 2  (0) 2025.03.19
[iOS] Swift 문법 복습  (0) 2025.03.18