티스토리 뷰
iOS 면접 준비를 위해 정리되어 있는 예상 질문을 참고로 하나씩 정리를 시작해보려 한다.
- 아래 링크 참고
옵셔널
옵셔널 많이 사용했고, 개념도 나름 이해한다고 생각했는데 막상 질문에 답하려고 하니 대답할 자신이 없다,,,
1️⃣ Swift에서 옵셔널이란 무엇이며, 언제 사용해야 하나요?
: 옵셔널은 Swift 언어의 중요한 특징 중 하나입니다. Swift는 변수나 상수가 값이 있을 수도 있고 없을 수도 있는 지를 명시적으로 표현하기 위해 옵셔널을 제공합니다. 즉, 값이 nil일 수 있는지 여부를 나타내며, nil은 "값이 없음" 을 나타냅니다.
✏️ 설명
옵셔널은 값이 있을 수도 있고, 없을 수도 있다!!
일반적인 프로그래밍 언어에서는 값이 null인 변수에 접근하면 프로그램이 종료된다.
하지만 swift는 안정성이 장점이기 때문에 옵셔널을 사용해서 값이 없는 변수에 접근해도 프로그램이 종료되지 않도록 한다.
옵셔널 사용방법은 nil 값이 들어갈 수 있는 변수 뒤에 ?를 붙이면 된다.
name은 옵셔널이지만 초기화되지 않았으므로 nil 값을 가진다. 이때 name 변수를 출력하면 nil이 나오게 된다.
swift에서 변수를 선언할 때 초기값을 주지 않으면 옵셔널 변수는 자동으로 nil로 초기화된다.
var name: String?
var optionalName: String? = "Hee"
print(optionalName) // 출력: Optional("Hee")
print(name) // 출력: nil
optionalName 변수는 Optional에 감싸져서 출력된 걸 확인할 수 있다.
옵셔널 값은 일반 타입과 결합하거나 연산할 수 없기 때문에 옵셔널 값을 사용하려면 옵셔널 바인딩을 해야한다!!!
2️⃣ 옵셔널 바인딩과 강제 언래핑의 차이점은 무엇인가요?
옵셔널 바인딩: 옵셔널 값을 안전하게 추출하여 사용하기 위한 방법 중 하나입니다. 옵셔널이 값이 있는지를 확인하고, 그 값을 다른 변수에 할당하여 사용합니다. 이는 if-let 구문이나 guard 구문을 사용하여 수행해야 합니다.
강제 언래핑: 옵셔널 값을 강제로 추출하는 방법입니다. 만약 옵셔널 값이 nil이 아니라고 확신할 때 사용합니다. 하지만 값이 nil인 경우 런타임 오류가 발생할 수 있으므로 주의해서 사용해야 합니다.
✏️ 설명
옵셔널 값은 일반 타입과 직접적으로 결합하거나 연산할 수 없는데 이는 옵셔널 값이 있을 수도 없을 수도 있기 때문이다.
따라서 옵셔널 값을 사용할 때는 옵셔널 바인딩을 통해 안전하게 값을 추출하고 사용해야 한다.
🟡 옵셔널 바인딩 예제
- if-let
: optionalName이라는 옵셔널 변수에 값을 할당하고 if-let 구문을 사용하여 옵셔널 값을 안전하게 추출하여 name 상수에 바인딩하고 있다. 만약 optionalName이 nil 값이라면 if-let 구문의 else 블록이 실행되어 "이름이 없습니다"를 출력한다.
let optionalName: String? = "Hee"
if let name = optionalName {
print("안녕하세요, \(name)님!")
} else {
print("이름이 없습니다.")
}
- guard
: greet 함수는 optionalName을 파라미터로 받고 있고, guard let 구문을 사용하여 optionalName을 안전하게 추출하여 name 상수에 바인딩한다. 만약 optionalName이 nil 값이라면 guard 구문의 else 블록이 실행되어 "이름이 없습니다"를 출력한다.
func greet(_ optionalName: String?) {
guard let name = optionalName else {
print("이름이 없습니다.")
return
}
// 여기서부터는 name이 안전하게 추출된 상태
print("안녕하세요, \(name)님!")
}
greet("Hee") // 출력: 안녕하세요, Hee님!
greet(nil) // 출력: 이름이 없습니다.
🟡 강제 언래핑
: optionalName이라는 옵셔널 변수를 강제 언래핑하여 값을 추출하고 있다. 이때 옵셔널 값이 nil이 아니라고 확신할 때 사용되며, 만약 값이 nil이라면 런타임 오류가 발생한다.
- 정상 코드
let optionalName: String? = "Hee"
let unwrappedName = optionalName!
print("안녕하세요, \(unwrappedName)님!")
- 오류 발생
let optionalName: String? = nil
let unwrappedName = optionalName!
print("안녕하세요, \(unwrappedName)님!") // 런타임 오류 발생!
3️⃣ 옵셔널 체이닝의 동작원리를 설명해주세요.
: 옵셔널 체이닝은 옵셔널 값들의 연속적인 체이닝을 가능하게 합니다. 만약 체인 중 하나의 값이 nil이라면, 전체 표현식의 결과는 nil이 됩니다. 이는 프로퍼티나 메서드를 호출할 때 옵셔널이 있는 경우 유용하게 사용됩니다.
✏️ 설명
옵셔널 체이닝은 대체 무엇인가???
.(dot)을 통해 내부 프로퍼티나 메서드에 연속적으로 접근할 때 옵셔널 값이 하나라도 있는 경우
=> 옵셔널 체이닝
아래의 코드 모두 옵셔널 체이닝이다.
person.address?.city
person?.address.city
즉, .(dot)으로 연결된 체인 중에 하나라도 옵셔널 값이 있으면 된다는 것
🟡 예제
: person이라는 인스턴스가 있고, 이 인스턴스가 address라는 옵셔널 프로퍼티를 가진다.
그리고 address 프로퍼티는 다시 city라는 옵셔널 프로퍼티를 가진다.
이렇게 옵셔널 체이닝을 사용해 최종적으로 city의 값에 도달할 수 있다.
struct Person {
var address: Address?
}
struct Address {
var city: String?
}
// Person 인스턴스 생성
let person = Person(address: Address(city: "Seoul"))
// 옵셔널 체이닝을 사용하여 address의 city에 접근
if let city = person.address?.city {
print("거주하는 도시: \(city)") // 출력: 거주하는 도시: Seoul
} else {
print("주소 정보를 찾을 수 없습니다.")
}
peson.address?city로 옵셔널 체이닝을 통해 city 프로퍼티에 접근하는 과정에서 address가 nil이기 때문에 옵셔널 체이닝이 중단되고 결과적으로 nil이 반환된다.
struct Person {
var address: Address?
}
struct Address {
var city: String?
}
// Person 인스턴스 생성
let person = Person(address: nil)
// 옵셔널 체이닝을 사용하여 address의 city에 접근
if let city = person.address?.city {
print("거주하는 도시: \(city)")
} else {
print("주소 정보를 찾을 수 없습니다.") // 출력: 주소 정보를 찾을 수 없습니다.
}
4️⃣ 암시적 언래핑 옵셔널을 사용하는 경우는 언제인가요?
: 암시적 언래핑 옵셔널은 선언할 때 옵셔널임을 명시하되, 나중에 nil이 될 가능성이 없는 경우에 사용됩니다.
예를 들어, 클래스의 프로퍼티 중 일부는 초기화 시점에 nil이지만, 이후에는 항상 값을 가질 것으로 확신할 때 사용됩니다.
이러한 경우 옵셔널 바인딩이나 강제 언래핑 없이도 옵셔널 값을 사용할 수 있습니다.
✏️ 설명
암시적 언래핑 옵셔널은 초기화된 이후에는 항상 값이 있을 것으로 예상되는 상황에서 사용된다,
이런 상황에서 옵셔널 바인딩이나 강제 언래핑 없이 코드를 간결하게 작성할 수 있다.
보통 옵셔널 타입의 변수를 선언할 때 뒤에 "?"를 붙였다면, 암시적으로 언래핑한 옵셔널은 뒤에 "!"를 붙여서 선언한다.
var age: Int! = nil // 암시적으로 언래핑한 옵셔널
var name: String? = nil // 일반 옵셔널
암시적으로 언래핑한 옵셔널도 옵셔널이기 때문에 값에 nil을 할당할 수 있고 값을 할당할 수도 있다.
var age: Int! = nil
age = 10
age = nil
보통 옵셔널과 다른 점이 뒤에 !를 붙인다는 것이다.
근데 !를 붙이는 건 강제 언래핑과 같은데 뭐가 다르다는 것이지..!? 이건 아래에서 설명하겠다.
둘 다 옵셔널 값을 강제로 추출하는 방법으로, nil값이 아니라고 확신할 때 사용한다.
강제 언래핑은 선언은 "?"을 붙이며 값을 추출할 때 변수 뒤에 "!"을 붙인다.
암시적 언래핑은 선언에 "!"을 붙이며 값을 추출할 때 옵셔널 바인딩이나 강제 언래핑 없이 값에 직접적으로 접근할 수 있다.
// 강제 언래핑
var optionalValue: Int? = 5
var forcedValue = optionalValue! // 옵셔널을 강제로 추출
print(forcedValue) // 출력: 5
// 암시적 언래핑 옵셔널
var implicitValue: Int! = 10
var unwrappedValue = implicitValue // 암시적 언래핑 옵셔널 사용
print(unwrappedValue) // 출력: 10
다시 돌아와서 암시적으로 언래핑한 옵셔널에 계속 알아보자면, age라는 옵셔널 값에 강제 언래핑을 하지 않아도 옵셔널이 벗겨진 상태로 사용 가능하다.
아래와 같이 "!"로 강제 언래핑하지 않아도 일반 상수처럼 사용할 수 있다.
// 암시적으로 언래핑한 옵셔널 선언
var age: Int! = 10
print(age + 10) // 20
---------------
// 일반 옵셔널 선언 + 강제 언래핑
var age: Int? = 10
print(age! + 10) // 20
nil 값일 때도 동일하게 사용할 수 있다.
두 경우 모두 nil이 들어있다면 runtime에 프로그램이 비정상적으로 종료된다.
// 암시적으로 언래핑한 옵셔널 선언
var age: Int! = nil
print(age + 10)
---------------
// 일반 옵셔널 선언 + 강제 언래핑
var age: Int? = nil
print(age! + 10)
🟡 uikit 예제
애플이 사용하는 암시적으로 언래핑한 옵셔널에 대한 대표적인 예시로 IBOutlet이 있다.
UIViewController의 IBOutlet은 스토리 보드에서 자동으로 초기화되므로 옵셔널을 사용하지만 뷰 컨트롤러가 초기화된 이후에는 항상 값이 있을 것으로 예상된다. 따라서 IBOutlet을 암시적 언래핑 옵셔널로 선언하여 편리하게 사용할 수 있다.
import UIKit
class MyViewController: UIViewController {
@IBOutlet weak var myLabel: UILabel! // 암시적 언래핑 옵셔널
override func viewDidLoad() {
super.viewDidLoad()
// 옵셔널 바인딩이나 강제 언래핑 없이도 직접 사용 가능
myLabel.text = "Hello, World!"
}
}
5️⃣ nil 병합 연산자(??)의 사용 예시를 들어주세요.
: nil 병합 연산자(??)는 옵셔널 값이 nil일 때 대체 값을 제공하는 연산자입니다. 만약 옵셔널 값이 nil이 아니라면 옵셔널 값을 그대로 사용하고 nil이라면 nil 병합 연산자(??) 오른쪽의 값을 사용합니다.
let optionalValue: Int? = nil
let result = optionalValue ?? 0 // 만약 optionalValue가 nil이면 0을 사용함
print(result) // 출력: 0
✏️ 설명
🟡 예제
1. 기본값 설정
: 값이 nil인 경우 기본값 설정할 때 사용
let userInput: String? = nil
let username = userInput ?? "Guest"
2. API 호출
: 외부 API 호출하거나 데이터 가져올 떄 반환값이 옵셔널인 경우
let responseData: String? = fetchDataFromAPI()
let parsedData = responseData ?? "No data available"
3. UI 초기화
: UI 요소 초기화 시에 옵셔널 값이 nil인 경우
let optionalColor: UIColor? = nil
let backgroundColor = optionalColor ?? UIColor.white
4. 옵셔널 체이닝 후 값 확인
: 옵셔널 체이닝을 사용한 후에 값이 nil인 경우
let optionalText: String? = someObject.someOptionalProperty?.someMethodReturningString()
let finalText = optionalText ?? "Default Text"
'스위프트' 카테고리의 다른 글
Codable 이해 (0) | 2024.04.18 |
---|---|
[Swift] - iOS 앱의 Life Cycle (0) | 2024.04.03 |
[Swift] - git 충돌 해결 (0) | 2024.03.23 |
[Swift] - Could not build Objective-C module 'Accessibility' 오류 (1) | 2024.02.26 |
[Swift] - 서브스크립트(Subscript) (2) | 2023.12.30 |