2025. 2. 1. 17:55ㆍiOS
Swift의 **옵셔널(Optional)**은 값이 있을 수도 있고 없을 수도 있는 변수를 안전하게 처리할 수 있도록 도와주는 개념입니다. 이는 nil을 허용하는 타입을 의미하며, Swift에서 널 포인터(nil pointer) 에러를 방지하기 위한 중요한 기능입니다.
1. 옵셔널이 필요한 이유
Swift에서는 nil을 기본적으로 허용하지 않습니다.
예를 들어, 아래 코드는 컴파일 오류가 발생합니다.
var name: String = "Swift"
name = nil // ❌ 오류 발생
Swift에서는 모든 변수는 반드시 값을 가져야 하며 nil을 허용하려면 명시적으로 옵셔널로 선언해야 합니다.
2. 옵셔널의 선언 방법
옵셔널은 변수 타입 뒤에 ?를 붙여 선언합니다.
var name: String? = "Swift"
name = nil // ✅ 가능 (옵셔널이므로 nil 저장 가능)
이제 name 변수는 "Swift" 또는 nil을 가질 수 있습니다.
3. 옵셔널의 기본 동작
옵셔널 변수는 값이 없을 수도 있기 때문에, 값을 직접 사용할 수 없습니다.
var name: String? = "Swift"
// print(name.uppercased()) // ❌ 오류 발생
옵셔널을 사용하려면 **안전하게 값을 꺼내는 방법(옵셔널 바인딩, 강제 언래핑 등)**을 사용해야 합니다.
4. 옵셔널 값 꺼내기 (Unwrapping)
(1) 강제 언래핑 (!)
옵셔널 값이 nil이 아님을 확신할 때 !를 사용하여 강제 언래핑할 수 있습니다.
var name: String? = "Swift"
print(name!) // ✅ "Swift"
하지만 값이 nil일 경우 런타임 오류가 발생하기 때문에, 강제 언래핑은 주의해서 사용해야 합니다.
var name: String? = nil
print(name!) // ❌ 런타임 오류 (Unexpectedly found nil)
(2) 옵셔널 바인딩 (if let / guard let)
옵셔널 바인딩을 사용하면 nil 여부를 안전하게 체크한 후 값을 사용할 수 있습니다.
✅ if let 사용 (안전한 언래핑)
var name: String? = "Swift"
if let unwrappedName = name {
print(unwrappedName) // ✅ "Swift"
} else {
print("name이 nil입니다.")
}
if let은 name이 nil이 아닐 경우 값을 unwrappedName에 할당하고 블록 내부에서 사용할 수 있도록 합니다.
✅ guard let 사용 (함수에서 조기 탈출)
func printName(_ name: String?) {
guard let unwrappedName = name else {
print("이름이 없습니다.")
return
}
print("이름은 \(unwrappedName)입니다.")
}
printName("Swift") // ✅ "이름은 Swift입니다."
printName(nil) // ✅ "이름이 없습니다."
guard let은 nil일 경우 즉시 함수에서 빠져나가게(return) 하여 코드의 가독성을 높입니다.
5. 옵셔널의 기본값 설정
(1) ?? (Nil-Coalescing Operator, 기본값 제공)
옵셔널 값이 nil일 경우 기본값을 제공할 때 ?? 연산자를 사용합니다.
var name: String? = nil
print(name ?? "기본값") // ✅ "기본값"
?? 연산자는 name이 nil이면 "기본값"을 사용합니다.
6. 옵셔널 체이닝 (?.)
옵셔널 체이닝을 사용하면 옵셔널 값이 있을 경우에만 메서드나 프로퍼티를 호출할 수 있습니다.
struct User {
var name: String
var address: String?
}
let user: User? = User(name: "Alice", address: "Seoul")
// 옵셔널 체이닝 사용
print(user?.address?.uppercased() ?? "주소 없음") // ✅ "SEOUL"
옵셔널 체이닝을 사용하면 nil일 경우에도 안전하게 nil을 반환하며, 런타임 오류를 방지할 수 있습니다.
7. 암시적 옵셔널 (! 사용)
옵셔널 변수 선언 시 ? 대신 !를 사용하면 **"값이 항상 존재한다고 가정"**하며, 자동으로 언래핑됩니다.
var name: String! = "Swift"
print(name) // ✅ "Swift"
하지만, nil이 들어가면 런타임 오류가 발생하기 때문에 사용 시 주의해야 합니다.
var name: String! = nil
print(name) // ❌ 런타임 오류 발생
💡 권장 사항:
! 대신 ?를 사용하고 옵셔널 바인딩으로 처리하는 것이 안전합니다.
8. 옵셔널의 활용 사례
(1) 딕셔너리에서 값 찾기
딕셔너리에서 키를 찾을 때 반환값은 옵셔널이므로, 값이 없을 경우 nil이 됩니다.
let scores = ["Alice": 90, "Bob": 85]
print(scores["Alice"]) // ✅ Optional(90)
print(scores["Charlie"]) // ✅ nil
값을 안전하게 가져오려면 옵셔널 바인딩을 사용합니다.
if let aliceScore = scores["Alice"] {
print("Alice의 점수는 \(aliceScore)점입니다.") // ✅ 90점
}
(2) Int 변환 시 옵셔널 반환
문자열을 정수로 변환하는 Int() 함수는 옵셔널을 반환합니다.
let number = Int("123") // ✅ Optional(123)
let invalidNumber = Int("ABC") // ✅ nil
(3) 함수의 옵셔널 반환값
함수의 반환값이 없을 수도 있을 경우, 옵셔널을 반환합니다.
func findIndex(of number: Int, in array: [Int]) -> Int? {
return array.firstIndex(of: number)
}
let numbers = [1, 2, 3, 4, 5]
print(findIndex(of: 3, in: numbers)) // ✅ Optional(2)
print(findIndex(of: 6, in: numbers)) // ✅ nil
9. 정리
개념설명
? | 옵셔널 선언 (값이 없을 수도 있음) |
! | 강제 언래핑 (값이 nil이면 오류 발생) |
if let | 안전한 옵셔널 바인딩 (값이 있을 경우 실행) |
guard let | 조기 탈출을 위한 옵셔널 바인딩 |
?? | 기본값 제공 (Nil-Coalescing) |
?. | 옵셔널 체이닝 |
! (암시적) | 옵셔널이지만 항상 값이 있다고 가정 |
옵셔널은 Swift에서 nil로 인해 발생하는 런타임 오류를 방지하고, 안전한 프로그래밍을 가능하게 해주는 핵심 기능입니다. 🚀
'iOS' 카테고리의 다른 글
[iOS] Performance Trace란? (0) | 2025.02.01 |
---|---|
[iOS] Core Data vs Realm (0) | 2025.02.01 |
[iOS] HTTPCookieStorage와 WKHTTPCookieStore 차이 (0) | 2025.01.30 |
[iOS] 웹뷰(WebView)기반 앱 개발 시 주의할 점 (2) | 2025.01.30 |
[iOS] SwiftUI와 Combine (2) (0) | 2025.01.28 |