TIL(Today I Learned)

UserDefaults?
  • 가장 기본적인 데이터베이스로, 복잡하고 큰 용량의 데이터보다는 간단한 데이터 저장에 적합
  • 앱이 삭제되면 데이터도 함께 삭제
  • 데이터가 암호화되지 않고 그대로 저장되기 때문에 보안과 관련된 정보는 저장하지 않는 것을 권장
  • UserDefaults는 싱글톤 객체
  • thread safety 보장
데이터 저장 방법
func set(Any?, forKey: String)
    Sets the value of the specified default key.
func set(Float, forKey: String)
    Sets the value of the specified default key to the specified float value.
func set(Double, forKey: String)
    Sets the value of the specified default key to the double value.
func set(Int, forKey: String)
    Sets the value of the specified default key to the specified integer value.
func set(Bool, forKey: String)
    Sets the value of the specified default key to the specified Boolean value.
func set(URL?, forKey: String)
    Sets the value of the specified default key to the specified URL.
  • key-value 쌍으로 데이터를 저장
  • NSData, NSString, NSNumber, NSDate, NSArray, NSDictionary 유형의 객체도 저장 가능
  • 사용자 정의 객체는 NSKeyedArchiver, Codable을 이용해 Data 형태로 저장 필요
  • deinit시 자동으로 synchronize()를 호출하며 이때 데이터가 저장 -> 강제 종료되면 저장되지 x
데이터 접근 방법
func object(forKey: String) -> Any?
    Returns the object associated with the specified key.
func url(forKey: String) -> URL?
    Returns the URL associated with the specified key.
func array(forKey: String) -> [Any]?
    Returns the array associated with the specified key.
func dictionary(forKey: String) -> [String : Any]?
    Returns the dictionary object associated with the specified key.
func string(forKey: String) -> String?
    Returns the string associated with the specified key.
func stringArray(forKey: String) -> [String]?
    Returns the array of strings associated with the specified key.
func data(forKey: String) -> Data?
    Returns the data object associated with the specified key.
func bool(forKey: String) -> Bool
    Returns the Boolean value associated with the specified key.
func integer(forKey: String) -> Int
    Returns the integer value associated with the specified key.
func float(forKey: String) -> Float
    Returns the float value associated with the specified key.
func double(forKey: String) -> Double
    Returns the double value associated with the specified key.
func dictionaryRepresentation() -> [String : Any]
    Returns a dictionary that contains a union of all key-value pairs in the domains in the search list.
  • 기본 타입의 데이터에 접근시에는 값이 해당 타입으로 변환되기 때문에 타입 캐스팅을 안해줘도 되지만 이외의 타입은 Any?타입으로 값이 반환되기 때문에 타입 캐스팅이 필요
데이터 삭제 방법
func removeObject(forKey: String)
Removes the value of the specified default key.
  • removeObject()메소드를 이용하여 value 키의 데이터를 삭제하고 값을 출력하면 기본값인 0이 출력
  • 해당 키에 nil을 할당해도 removeObject()메소드 사용과 동일하게 동작
  • 없는 키를 삭제해도 에러 발생 x
register(defaults:)
  • return타입이 옵셔널이 아닌 메소드의 기본값 - Int, Float, Double = 0 / Bool = false
  • return타입이 옵셔널인 메소드를 사용하면 nil 반환 -> 옵셔널 바인딩 필요 -> register(defaults:) 사용
UserDefaults.standard.register(defaults: [
    "SomeKey" : "Some Message"
])
let data = UserDefaults.standard.string(forKey: "SomeKey")
print(data) //Optional("Some Message")
사용자 정의 타입 get, set
  • 아카이빙 - struct같은 사용자 정의 타입의 객체를 Data형과 같이 바이트 형태로 변경하는 작업
  • 언아카이빙 - 메모리, 디스크에 저장된 Data 형태의 바이트를 struct같은 사용자 정의 타입의 객체로 변경하는 작업
  • set 과정
    1. 사용자 정의 타입에 Codable 프로토콜을 채택
    2. JSONEncoder 객체 생성
    3. JSONEncoder를 이용해 Data타입으로 변경
    4. UsweDefaults에 저장
        if let encoded = try? encoder.encode(memo) {
        UserDefaults.standard.set(encoded, forKey: "Memo")
        }
      
  • get 과정
    1. JSONDecoder 객체 생성
    2. JSONDecoder를 이용해 사용자 정의 타입으로 변경
    3. 원하는 변수에 저장
        let decoder: JSONDecoder = JSONDecoder()
        if let data = UserDefaults.standard.object(forKey: "Human") as? Data,
        let human = try? decoder.decode(Human.self, from: data) {
        }   
      
UserDefaults의 성능은?
  • 기본적으로 plist에서 값을 읽은 뒤에 메모리 상에서 모든 데이터를 관리
  • 동일한 키의 데이터를 읽으려고 하면 메모리에 있는 값을 전달 = 메모리 캐싱
  • synchronize()가 호출된 뒤 파일로 동기화되기 전까지는 메모리 상에만 존재
  • 단, 대규모 데이터를 저장한다면 앱을 실행할 때마다 메모리에 올리는 데이터의 양이 많아지므로 성능 저하 가능성 존재

댓글남기기