하루에 0.01%라도 성장하자

Develop/iOS

Swift 옵셔널(Optional)

뚠님 2019. 5. 8. 16:01
반응형

Swift

 

Swift의 핵심이라고 할 수 있는 옵셔널(Optional)이다.

( 이게 왜 핵심인지 나는 아직 잘 모르겠다... ㅋㅋ )

 

옵셔널(Optional)

 

  • 값이 있을수도, 없을 수도 있음을 표현함.
  • nil이 할당될 수 있는지 표현

[ 옵셔널의 형태 ]

enum Optional<Wrapped> : ExpressibleByNilLiteral{
    case none
    case some(Wrapped)
}

 

옵셔널을 쓰는 이유

 

  • 명시적 표현
    • nil의 가능성을 코드만으로 표현이 가능하다. ( 문서에 null가능 여부를 별도로 쓸 필요가 없다. )
    • 따라서 문서/주석 작성 시간 절약.
  • 안전한 사용
    • 전달 받은 값이 옵셔널이 아니라면 nil체크 없이 사용 가능 ( nil일 수가 없기 때문에 )
    • 예외 상황을 최소화 하는 귀찮지만 안전한 코딩
    • 효율적 코딩

 

옵셔널 문법

 

[ 선언 ]

 

선언하는 방법은 다양하다.

let optionalVar : Optional<Int> = nil;
let optionalVar : Int? = nil;
let optionalVar : Int! = nil;

 

 

[ 느낌표를 이용한 선언(!) ]

 

암시적 추출 옵셔널 ( Implicitly Unwrapped Optional )

var optionalVar : Int! = 100;


switch (optionalVar){
    case .none:
    	print("this optional var is nil");
    case .some(let vale):
    	print("var is \(optionalVar)");
}

optionalVar = optionalVar + 1; //변수처럼 사용 가능

optionalVar = nil // nil 할당 가능.

 

[ 물음표를 이용한 선언(?) ]

 

옵셔널(Optional)

var optionalVar : Int? = 100;


switch (optionalVar){
    case .none:
    	print("this optional var is nil");
    case .some(let vale):
    	print("var is \(optionalVar)");
}



optionalVar = optionalVar + 1; //변수처럼 사용 불가

optionalVar = nil // nil 할당 가능.

 

옵셔널 추출

 

옵셔널로 지정된 변수를 추출하여 사용 할 수 있어야 한다.

이때 우리는 총 세가지의 방법으로 옵셔널 변수를 가져와 사용할 수 있다.

 

  • 옵셔널 바인딩 (Optional Binding)
  • 옵셔널 체이닝 (Optional Chaining)
  • 옵셔널 강제추출 (Forced Unwrapping)

 

옵셔널 바인딩(Optional Binding)

 

옵셔널을 사용하기 전에 먼저 값이 있는지 체크하는 방법.

 

func printMyInfo(_name:String){
    print(_name);
}

var myName : String? = nil;
if let name = myName {
    printMyInfo(_name : name);
}

 

printMyInfo 함수는 입력된 _name 값을 출력한다.

myName변수는 String?형태의 옵셔널 변수이고 초기값으로 nil이 할당되었다.

 

밑에 줄이 핵심인데, if let을 이용해 name이라는 변수를 만들어주고 거기에 myName(옵셔널변수) 값을 할당해 값이 있는지 없는지 확인한다.

 

값이 있으면 printMyInfo함수를 실행하고 없으면 동작하지 않는다.

 

즉 if let(또는 if var)는 옵셔널 변수에 값이 있는지 nil인지 확인을 해주는 방법이며 값이 있을경우 printMyInfo함수를 바인딩 해준다.

 

var num : Int? = 200;
if let tempNum = num, num>=200{
    print("200이상입니다.");
}

조건 : num 값이 nil이 아니고 200이상이면 print를 실행하라.

 

위 코드와 같이 여러개의 조건을 같이 진행 할 수 있다.

 

 

옵셔널 체이닝(Optional Chaining)

 

옵셔널 체이닝은 하위 property에 optional값이 있는지 연속적으로 확인하면서 중간에 nil값이 하나라도 발견되면 nil이 반환되는 형식이다.

 

class NumberTest {
    var number : Numbers?
}


class Numbers {
    var num = 10;
}

let tempNum = NumberTest(); // NumberTest 클래스를 만들었지만 그 안에 Numbers클래스를 생성해주지 않았기 때문에 Numbers안에 있는 변수 num은 nil로 초기화된다.

if let numberCount = tempNum.NumberTest?.num { // 옵셔널 체이닝 부분.
    print("숫자는 \(numberCount) 입니다.");
} else {
	print("없음");
}

 

하위 Property Optinal값이 있는지 연속적으로 확인하면서 중간에 하나라도 nil이 발견되면 nil이 반환되는 것이 옵셔널 체이닝 방식.

 

옵셔널 강제 추출 ( Optional Forced Unwrapping )

 

사용하려는 옵셔널 변수가 nil값이 아니라고 '확신'할 때 사용한다.

nil값이 아닌 것을 확신한다면 굳이 "값이 있나요? nil인가요?"라고 물어볼 필요가 없다는 것이다.

 

다만 인생사 쉽게 확신하면 안되는 것처럼 코드에서도 지양하는 방법이다.

 

let intValue;
let value : Int? = 10;

intValue = value!;

위 코드 처럼 확신한다면 !를 옵셔널 변수 뒤에 사용하여 강제로 넣을 수 있다.

이는 문법적으로 문제가 없기 때문에 컴파일러는 에러를 뱉지 않고, 만약 value값이 nil일 경우 런타임 에러가 발생하게 된다.

 

따라서 '확신'이 있을때만 사용하는 것이 좋다!

 

 

Swift는 안정성이 뛰어난 언어라고 하는데, nil값을 최대한 발생하지 않도록 제약하기 때문인거 같다.

( 아직은 불편하고 귀찮은 문법 .;;; )

 

추가 공부 & 참고 사이트

 

강의로는 정보나 설명이 조금 부족해 굉장히 정리가 잘된 블로그를 찾아 공유한다.

https://zeddios.tistory.com/16

반응형

'Develop > iOS' 카테고리의 다른 글

Swift 열거형 (enum)  (0) 2019.05.08
Swift 구조체 (Struct)  (0) 2019.05.08
Swift 반복문  (0) 2019.05.08
Swift Swift의 Switch  (0) 2019.05.08
SandBox 제약으로 보안을 강화한다.  (0) 2019.05.04