• 옵셔널 타입

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

    • 값을 반환할 때 오류가 발생할 가능성이 있는 값은 옵셔널 타입이라는 객체로 감싸서 반환한다.
    • Int(“Hi”) 은 정수 값을 반환할 수 없음, 아무런 값도 반환할 수 없다는 의미로 nil을 반환
    • Swift에서 기본 자료형(Int, Double, String 등)은 nil값을 저장할 수 없다
    • nil도 저장하려면 옵셔널 타입으로 선언해야 한다.
      Int("404")   	     //Int("404") 
      print(Int("404"))  //Optional(404)
      print(int("404")!) //404
      print(Int("HI"))   //nil   !붙이면 오류
    
    • 옵셔널 사용이유
      • 옵셔널 타입만이 값을 갖지 않는다는 의미의 nil 값을 가질 수 있음
      var ho = nil            // error
      var ho : Int? = nil     // OK
      var ho : Int?           // OK, 위와 같은 코드  옵셔널 변수는 초기화하지 않으면 자동으로 nil로 초기화
      var sh : String = nil   // 유효하지 않은 코드
      let myConstant = nil    // 유효하지 않은 코드
    
  • 옵셔널 타입 강제 언래핑(forced unwrapping)

      var h : Int?  	  //옵셔널 정수형 변수 h 선언
      var s : Int = 0
      h = 10    	      // 주석처리시 기본값 nil
      print(h)  	      // Optional(10)
      print(h!) 	      //forced unwrappint해서 10이 나온다
      print(s)
      //h = h+1      	  // 자료형 대입이 불가능하다 (타입이 달라서)
      //s = h
    
      var h : Int?
      h = 20
      if h != nil {     // !=공백 주의 붙여쓰면 h를 강제 언레핑후 nil 대입에러 (if x!=nil)
        print(h!)       //20
      }
      else{
        print("nil")
      }
      var sh : Int?
      if sh != nil{
        print(sh!)
      }
      else{
        print("nil")  //nil
      }
    
  • 옵셔널 바인딩(Optional binding)

      var h : Int?
      h = 20
      if let hh = h { 	//옵셔널에 할당된 값을 임시 변수 또는 상수에 할당
        print(h,hh)   	//Optional(20) 20
      }
      else{
        print("nil")
      }
      var sh : Int?
      if let hh = sh{
        print(hh)
      }
      else{
        print("nil")  	//nil
      }
    
    • 여러 옵셔널 바인딩 사용시 콤마(,) 사용
      var h : String?
      var s : String?
      h = "hyeon ho"
      s = "shin hyeon"
      if let ho = h, let sh = s { 
        print(ho,sh)   	//hyeon ho shin hyeon
      }
      else{
        print("nil")
      }
    
      var h : Int?
      var s : Int?
      h = 20
      s = 30
      if let hh = h, sh = s { 	
        print(hh,sh)   	//20 30
      }
      else{
        print("nil")
      }
    
  • 암묵적 언레핑 (폐지)
    • 옵셔널이 항상 유효한 값을 가질 경우 옵셔널이 암묵적인 언래핑(implicitly unwrapped)이 되도록 선언할 수도 있다.
    • 클래스 초기화에서 많이 사용한다.
      var s : String? 	//옵셔널 변수 선언방법 1
      var h : Int! 	//옵셔널 변수 선언방법 2
      s = "shin ho"
      h = 20
      print(s,h) 	//Optional("shin ho") Optional(20)
      //swift4 버전까지는 y는 그냥 20이 나왔음, swift5부터는 Optional(20)
    
  • 형 변환 (Upcasting)
    • 상속 관계가 있는 클래스들끼리만 타입 캐스팅 가능하다.
    • as 연산자를 이용한 타입 변환(type casting)
    • 자식인스턴스 as 부모클래스 = > upcasting 안전한 캐스팅. 자식이 추상화됨
      let myButton: UIButton = UIButton()
      let myControl = myButton as UIControl //자식인스턴스 as 부모 클래스
    
      //자식인스턴스인 myButton을 부모 클래스형으로 형 변환
    
  • 형 변환 (Downcasting)
    • 부모 인스턴스를 자식 클래스로 변환하는 데 사용한다.
      • 성공 확신이 있으면 [as!] 키워드를 사용하며 강제 변환(forced conversion)
      • 성공 확신이 없으면 [as?] 를 사용하여 안전하게 변환
        • 부모인스턴스 as! 자식클래스 // downcasting 일반 타입으로 반환
        • 부모인스턴스 as! 자식클래스 // downcasting 옵셔널 타입으로 반환
        // 확신 있을때
        let myScrollView: UIScrollView = UIScrollView() //부모 인스턴스
        let myTextView = myScrollView as! UITextView    //부모인스턴스 as! 자식클래스
      
        // 확신 없을때
        if let classB = classA as? UITextView {         //옵셔널형이므로 옵셔널 바인딩을 수행
        print(Type cast to UITextView succeeded)
        } else {
        print(Type cast to UITextView failed)
      
  • 타입 검사(is)
    • is 키워드를 이용하여 값의 타입 검사(type check)
      class H {}	
      var h : H = H()
      if h is H{      //지정된 객체가 H 라는 클래스의 인스턴스인지 검사
      print("Hello") 	//Hello    h는 H의 인스턴스이다
      }