TIL 15

오늘 한 일 / 배운점

  • 개인 과제 Lv.2 (진행중)

  • 8/7 19:00 보충학습 : OT 및 옵셔널 (HG튜터님)

    • null? nil?

      null : 메모리에 객체를 가리키는 포인터가 없음 객체가 없음 -> 접근하는 순간 에러

      // nullPointerException
      var optionalName: String?
      print(optionalName)
      

      nil : 값이 없는 상태를 나타내는 키워드

      var str = ""
      
    • 옵셔널 선언

      ? 타입으로 선언하는 건 간략화된 표현.

      let num1: Int? = 2 // 간편표기
      let num2: Optional<Int> = 3 // 정식 문법
      
    • 옵셔널은 어떻게 구현되어 있는가

      Optional은 enum 타입이고 값이 제네릭으로 선언되어 있고 저장되어 있다 옵셔널을 타고 가보면 이렇게 정의되어 있다

      @frozen public enum Optional<Wrappped> : ExpressibleByNilLiteral {
        case none
        case some(Wrapped)
        // ... 생략
      }
      
    • nil : 객체 O / 값 X

      nil 키워드는 메모리에 객체가 없다는 것이 아니라 객체는 생성되어 있지만 값만 없는 것

      Optional.none = nil // Optional.none -> 객체가 생성이 된 것, 메모리 자체에 객체가 없는게 X
      
      func address(of object: UnsafeRawPointer) -> String{
        let address = Int(bitPattern: object)
        return String(format: "%p", address)
      }
      
      var optionalName1: String? // nil
      var optionalName2: String? // nil
      
      address(of: &optionalName1) // "0x102784770"
      address(of: &optionalName2) // "0x102784780"
      
    • 옵셔널 사이의 연산은 불가!

      var numberOne: Int? = 3 
      var numberTwo: Int? = 5
      print(numberOne + numberTwo) // 에러 : enum+enum하는꼴이기때문에 연산이 불가능
      
    • 옵셔널 언래핑

      var string: String? = "hello"
      
      1. 강제 언래핑(!)
      print(string!) // hello
      
      1. if let 바인딩 : 바인딩이 된다면 특정 작업을 하겠다
      if var s = string {
      	print(s) // hello
      }
      
      1. nil coalescing(??) : 더 큰 덩어리로 합친다
      string = "a"
      // string이 Optional<String> 타입라면 반.드.시 ?? 뒤에 값을 String 타입의 객체를 넣어주어야 함
      var string2 = string ?? "bye" // nil인 경우에는 bye를 쓰겠다!
      print(string2) // hello
      

과제

  • 개인 과제 Lv.2

느낀점

과제 중에 지금은 단순히 입력값을var toDoTasks = [String]() 이 배열에 담고 있었는데
입력일 시도 담고 싶고, 완료 처리 여부도 담고 싶은데 딕셔너리에 담는다면 쌍으로 밖에 안 담기는 것 같고
var toDoTasks = [키:값]() 이렇게 딕셔너리로 바꾼다 했을 때
값 부분에 배열을 넣어 중첩해서 쓴다면..?

var toDoTasks = [String: [String]]()

// 값 추가하기
toDoTasks["밥먹기"] = ["2023-08-07 12:00:00", "0"]
toDoTasks["화장실가기"] = ["2023-08-07 13:50:00", "1"]

// 값 조회하기
let task1 = toDoTasks["밥먹기"] // Optional(["2023-08-07 12:00:00", "0"])
let task2 = toDoTasks["화장실가기"] // Optional(["2023-08-07 13:50:00", "1"])

이런 식으로 이거를 내가 원하는 Date, Bool 타입으로 해서

import Foundation

var toDoTasks2 = [String: [Date: Bool]]()

// 값 추가하기
toDoTasks2["밥먹기"] = [Date(): false]
toDoTasks2["화장실가기"] = [Date(): true]

// 값 조회하기
let task3 = toDoTasks2["밥먹기"] // Optional([2023-08-07 08:57:24 +0000: false])
let task4 = toDoTasks2["화장실가기"] // Optional([2023-08-07 08:57:24 +0000: true])

이렇게 적용해가면 될까 싶은데..
코드를 돌려보면 돌아가긴 하는데 왠지 바람직한 코드는 아닌 것 같은 느낌이 들어서
중간에 Codable 프로토콜(Encodable : JSON으로 변환, Decodable : 변환한 JSON을 다시 풀음)이란 걸 발견해서 그걸로 열심히 해보다가 뭐가 계속 막혀서 다시 위의 거로 해보다가 여기저기서 에러 나고 해서…
결국 삽질만 하다가 끝났다
내일 방법을 더 찾아봐야겠다