티스토리 뷰

출처

http://kka7.tistory.com/2




옵셔널 (Optional)


Optional 은 Objective-C 에서 포인터에 nil 을 사용하는 것보다 안전하고 쓰임새가 많으며
Swift 의 강력한 기능들 중에 핵심이다.

옵셔널은 값이 없을 수 있는 상황에서 사용한다.
옵셔널은 두가지 가능성을 표현한다.

- 값이 있고, 값에 접근하기 위해 옵셔널은 unwrap 할 수 있다.
- 값이 전혀 없다.

옵셔널의 개념은 Objective-C 에서는 없다.
가까운 것으로는 메소드가 nil 을 반환하거나 객체를 반환하는 것이며
nil 은 유효한 객체가 없다라는 것을 의미한다.

하지만, 이것은 객체에 대해서만 동작한다.
구조체, 기본적인 C 타입, 열거형의 값에 대해서는 동작하지 않는다.

Swift 의 옵셔널은 특별한 상수가 필요하지 않으며 
모든 타입에 대해 값이 없다는 것을 나타낸다.


아래 예제는 초기화를 사용하여 String 을 Int 로 변환을 시도한다.
만약, String 값이 Int 로 Parsing 이 불가능한 값일 수 있으므로
Int(possibleNumber) 는 Optional <Int> 를 반환한다.

let possibleNumber = "123"

let convertedNumber = Int(possibleNumber)

print(type(of: convertedNumber))    //Optional<Int>

print("Converted Number is \(convertedNumber)")     //Converted Number is Optional(123)




nil

값이 없는 상태에 대해서 특별한 값 nil 을 할당하여 옵셔널 변수에 설정한다.

nil 은 옵셔널이 아닌 상수나 변수에 사용할 수 없다.
코드에서 특정 조건에서 값이 없는 동작을 해야하는 상수나 변수가 필요하면
Optional 값으로 선언해야한다.

옵셔널 변수에 기본 값을 제공하지 않고 정의하면
변수는 자동적으로 nil 로 설정한다.

Swift 의 nil 은 Objective-C 의 nil 과 다르다.
Objective-C 에서의 nil 은 존재하지 않는 객체에 대한 포인터이다.
Swift 에서의 nil 은 포인터가 아니다. 특정 타입의 값이 없다. 라는 뜻이다.


If 문과 강제 언래핑 (If & Forced Unwrapping)

nil 대신에 옵셔널을 비교해서 옵셔널 값을 가지고 있는지 찾기위해
If 문을 사용할 수 있다.
옵셔널에 값이 있으면 nil 이 아니다.

if convertedNumber != nil {

    print("convertedNumber has value")

}


옵셔널에 값이 포함되어 있다고 확신한다면
옵셔널의 이름 뒤에 느낌표를 붙여서 값에 접근한다.
느낌표의 역할은 "옵셔널에 확실히 값이 있는 것을 알고 사용하라" 라는 것을 뜻한다.

! 를 사용할 대 존재하지 않는 옵셔널 값에 접근하려고 하면 runtime error 가 발생한다.
! 를 사용하기 전에 nil 이 아닌지 확인해야한다.

if convertedNumber != nil {

    print("converted Number is \(convertedNumber!)"//converted Number is 123

}




옵셔널 바인딩 (Optional Biniding)

옵셔널 값이 있는지 찾기 위해 옵셔널 바인딩을 사용하여
임시 상수나 변수로 사용할 수 있게 해준다.
옵셔널 바인딩은 if 와 , 로 구분하고
그 값을 상수나 변수로 추출한다.


if let constantNumber = convertedNumber {

    print(constantNumber)

}


if let actualNumber = Int(possibleNumber) {

    print("\"\(possibleNumber)\" has an integer value of \(actualNumber)")

} else {

    print("\"\(possibleNumber)\" could not be converted to an integer")

}


위 코드의 뜻은 Int(possibleNumber) 로 나온 Optional <Int> 값이 값이 있다면

옵셔널에 포함된 값으로 새로운 상수 actualNumber 를 설정한다. 라는 것이다.


actualNumber 는 Optional 값이 아니기 때문에 unwrap 해서 사용할 필요가 없다.

꼭 상수가 아니라 변수도 사용할 수 있다.


필요하다면 하나의 If 문 안에서 , 로 구분하여 여러개의 옵셔널 바인딩과

Boolean 조건들을 포함할 수 있다.


if let firstNumber = Int("4"),

    let secondNumber = Int("42"),

    firstNumber < secondNumber && secondNumber < 100 {

    

    print("\(firstNumber) < \(secondNumber) < 100")

}




암시적으로 언래핑된 옵셔널 (Implecitly Unwrapped Optionals)

옵셔널은 상수나 변수가 "값 없음" 을 가지도록 허용해주는 것이다.


프로그램 구조 상 처음에 값을 설정한 후에 옵셔널이 항상 값을 가지고 있는 것이

분명할 때가 있다. (nonnull 의 경우)


이런 종류의 옵셔널은 암시적으로 언레핑된 옵셔널로 정의된다.

옵셔널로 만들고자 하는 타입의 뒤에 물음표 대신 느낌표를 붙여준다.


let possibleString: String? = "An optional string."

let forcedString: String = possibleString// requires an exclamation mark

let assumedString: String! = "An implicitly unwrapped optional string."

let implicitString: String = assumedString



나중에라도 nil 이 될 가능성이 있을 때 암시적으로 언래핑된 옵셔널은 사용하지 않아야한다.

변수가 살아있는 동안 nil 값에 대해 확인이 필요하면 일반 옵셔널을 사용해야한다.


값이 포함되어있는지 확인하기 위해 암시적으로 언래핑된 옵셔널을 일반 옵셔널처럼 처리할 수 있다.


if assumedString != nil {

    print(assumedString)

}


하나의 문장에서 값을 확인하고 언래핑하기 위해

암시적으로 언래핑된 옵셔널을 옵셔널 바인딩으로 사용할 수 있다.


if let definiteString = assumedString {

    print(definiteString)

}





오류 처리 (Error Handling)

함수의 성공이나 실패를 알리는 방법에는
옵셔널을 사용하는 방법과
오류 처리로 실패의 근본적인 원인을 파악하는 방법이 있다.

오류 처리는 필요에 따라 프로그램의 다른 부분으로 오류를 전달한다.

오류가 발생할 수 있는 함수는 throws 라는 키워드를 함께 적어준다.

func canThrowAnError() throws {

    // this function may or may not throw an error

}


함수 호출에서 오류를 던질 수 있을 때 try 키워드를 앞에 붙여준다.
Swift 는 자동으로 catch 절에 의해 처리할 때까지 
현재 영역에서 바깥쪽으로 오류를 전달한다.

do {

    try canThrowAnError()

} catch {

    // handle error

}


do {

    try canThrowAnError()

catch let error as NSError {

    // handle error

}


do 키워드는 새로운 포함범위를 만들며

하나 이상의 catch 절에 오류를 전달한다.




Assert

특정 조건을 충족하지 못해 코드를 계속 실행하는 것이 불가능한 경우
강제로 assertion 을 수행하여 코드 실행을 종료하도록 하여
디버깅할 기회를 얻을 수 있다.

assertion 은 실시간으로 Boolean 조건이 정확히 true 인지 검사한다.
조건이 false 라면 앱을 종료한다.

let age = -3

assert(age >= 0, "A person's age cannot be less than zero")










공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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
글 보관함