Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Archives
Today
Total
관리 메뉴

브래의 슬기로운 코딩 생활

2 - 옵셔널 (optional), as(형 변환), is(타입 검사), Any와 AnyObject 본문

2 - 겨울방학/Swift 복습

2 - 옵셔널 (optional), as(형 변환), is(타입 검사), Any와 AnyObject

김브래 2023. 12. 26. 12:14

Int형 vs Optional Int형

10

 

Int 

Int 형 값을 저장
- var x : Int = 10

 

Optional(10)

 

Int? / Int!

Int형 값을 저장 or 값이 없음(nil)

- var y : Int? = 10 

- var z : Int! 

 

옵셔널 타입(매우 중요)

값을 반환할 때 오류가 발생할 가능성이 있는 값은 옵셔널 타입이라는 객체로 감싸서 반환함
- Swift에서 기본 자료형(Int, Double, String 등)은 nil값을 저장할 수 없음
- nil을 저장하려면 옵셔널 타입으로 선언해야 함

 

옵셔널 타입은 변수 또는 상수에 아무런 값이 할당되지 않는 상황을 안전하게 처리하기 위한 방법 제공

 

옵셔널 타입 변수를 선언하기 위해서는 타입 선언부 뒤에 “?” 문자를 씀

- 주의 : 변수명 뒤에 “?”하는 것 아님

 

index라는 이름의 옵셔널 Int 변수를 선언
- var index: Int?
- index 변수는 정수 값을 갖거나 아무 값도 갖지 않을 수 있음(nil) 

 

옵셔널 타입 강제 언래핑(forced unwrapping) 1

- 옵셔널 변수에 값이 있으면 옵셔널로 "래핑되었다(wrapped)"고 함
- 옵셔널에 래핑된 값은 강제 언래핑(forced unwrapping)으로 풀어줌

forced unwrapping : 옵셔널 변수 뒤에 !

var x : Int?
x = 10

 

if x != nil { // x가 nil이 아니면 / 주의 : if x!=nil 이라고 쓰면 안됨(띄어쓰기 주의)
print(x!)

else {
print("nil")
}

 

옵셔널 타입 강제 언래핑(forced unwrapping) 2 : optional binding

강제 언래핑하는 또 다른 방법으로, 옵셔널 바인딩(optional binding)을 이용하여 옵셔널에 할당된 값을 임시 변수 또는 상수에 할당

 

if let constantname = optionalName{  // nil이 아니면
//옵셔널 변수가 값이 있다면 언래핑해서 일반 상수 constantname에 대입하고 if문 실행
//값이 없다면 if문의 조건이 거짓이 되어 if문을 실행하지 않음
}

 

var x : Int?
x = 10
if let xx = x { //옵셔널 변수 x가 값(10)이 있으므로 언래핑해서 일반 상수 xx에 대입하고 if문 실행 
print(x, xx)    // if let x = x 라고 써도 된다.

else {
print("nil")
}

 

여러 옵셔널을 언래핑

여러 옵셔널 변수를 한번에 언래핑하는 방법은 콤마 사용

 

var pet1: String?
var pet2: String?
pet1 = "cat"
pet2 = "dog"
if let firstPet = pet1let secondPet = pet2 {
print(firstPet, secondPet)
} else {
print("nil")
}

 

두 가지 옵셔널 타입

옵셔널이 항상 유효한 값을 가질 경우 옵셔널이 암묵적인 언래핑(implicitly unwrapped)이 되도록 선언할 수도 있음

 

클래스의 아웃렛 변수 초기화에서 많이 사용(자동 생성되는 코드)

 

이러한 방법으로 옵셔널이 선언된다면 강제 언래핑이나 옵셔널 바인딩을 하지 않아도 값에 접근할 수 있음

 

암묵적인 언래핑으로 옵셔널을 선언하기 위해서는 선언부에 물음표(?) 대신에 느낌표(!)를 사용
- var x : Int? //옵셔널 변수 선언방법 1
- var y : Int! //옵셔널 변수 선언방법 2

왜 옵셔널을 사용하나요?

옵셔널 타입만이 값을 갖지 않는다는 의미의 nil 값을 가질 수 있음

 

옵셔널 변수는 초기화하지 않으면 자동으로 nil로 초기화

 

nil 값을 옵셔널이 아닌 변수나 상수에 할당할 수 없음
- var myInt = nil // error
- var myInt : Int? = nil // OK
- var myInt : Int? // OK, 위와 같은 코드
- var mystring : String = nil // error
- let myConstant = nil // error, 옵셔널 형을 지정해야 함

 

nil

옵셔널 변수에 nil을 할당하면 값이 없는 상태가 된다.
var serverResponseCode: Int? = 404 // serverResponseCode contains an actual Int value of 404

serverResponseCode = nil // serverResponseCode now contains no value

상수나 변수가 값이 없는 상태가 존재한다면 옵셔널 타입으로 선언해야 한다.

 

옵셔널 변수와 nil

옵셔널 변수에 초깃값을 할당하지 않으면 자동으로 nil이 할당됨
var surveyAnswer: String? // surveyAnswer is automatically set to nil

 

클래스 vs. 객체 vs. 인스턴스

클래스로부터 만들어진 객체를 인스턴스 라고 한다.

형 변환(as로 upcasting : 자식인스턴스를 부모클래스로 변환)

상속 관계가 있는 클래스들끼리만 타입 캐스팅 가능

 

자식(부모로부터 상속받아 더 많은 것을 가지고 있음)인스턴스를 부모로 캐스팅하는 것은 문제가 없음

 

as 연산자를 이용한 타입 변환(type casting)
- 자식인스턴스 as 부모클래스 // upcasting 안전한 캐스팅. 자식이 추상화됨
- 업캐스팅은 객체를 부모 클래스의 객체로 형 변환
- 형 변환은 성공할 것이기 때문에 보장된 변환(guaranteed conversion)
- UIButton은 UIControl의 자식 클래스이므로 안전하게 형 변환
- let myButton: UIButton = UIButton()
- let myControl = myButton as UIControl //자식인스턴스 as 부모 클래스
- 자식인스턴스인 myButton을 부모 클래스형으로 형 변환

형 변환(as! as?로 downcasting:부모인스턴스를 자식클래스로 변환)

다운캐스팅은 부모 인스턴스를 자식 클래스로 변환하는 데 사용

 

성공 확신이 있으면 as! 키워드를 사용하며 강제 변환(forced conversion)
- 변환이 안되면 crash

 

성공 확신이 없으면 as?를 사용하여 안전하게 변환
- 변환이 안되면 nil을 리턴하므로 옵셔널 타입으로 반환함

 

부모인스턴스 as! 자식클래스 // downcasting 일반 타입으로 반환 // 다운캐스팅이 반드시 성공할 것이라는 확신이 있을 때

 

부모인스턴스 as? 자식클래스 // downcasting 옵셔널 타입으로 반환. 확신이 없을 경우

타입 검사(is)

is 키워드를 이용하여 값의 타입 검사(type check)

 

- 지정된 객체가 MyClass라는 이름의 클래스의 인스턴스인지 검사
- 인스턴스가 해당 클래스인가?
- 인스턴스 is 클래스

 

if myobject is MyClass {
// myobject는 MyClass의 인스턴스이다
}

 

class A {}
var a : A = A()
if a is A{
print("Yes")
}

 

Any와 AnyObject

AnyObject(protocol)
- 범용 타입
- 상속관계가 아니라도 타입 캐스팅 가능한 타입
- 어떤 클래스의 객체도 저장 가능
- 가장 추상화된 최상위 개념(Objective-C의 id)
- 클래스만 허용하며 구조체나 열거형은 허용하지 않음


Any
- 클래스, 구조체, 열거형, 함수타입도 가능