티스토리 뷰
Core Data 데이터 저장하기
Car Entity를 만들어놓았으니, 데이터를 한번 저장해 보자
let myCar: [String: Any] = ["brand": "KIA", "color": "black", "price": 3000]
뷰 컨트롤러에 다음과 같이 딕셔너리 형태의 저장하고자 하는 값을 만들어주었다
이전 포스팅에서 context는 인스턴스들의 변화를 추적한다고 했다. 메서드라고 생각하면 편하지 않을까?
저장하는 메서드를 사용하기 위해서 context를 사용해야 하고, context 역시 다른 인스턴스들과 함께 container에 포함되어 있다
현재 persistent container는 AppDelegate에 있다
AppDelegate의 persistent containser에서 context를 불러오기
// AppDelegate 불러오기
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
// AppDelegate 안에 있는 persistentContainer에서 context 가져오기
let context = appDelegate.persistentContainer.viewContext
context를 가져왔으니 저장하고자 하는 데이터의 entity도 불러와야 한다
entity는 데이터 모델 내에서 데이터 유형을 나타낸다고 했다
우리가 저장할 데이터의 유형을 entity와 맞추면 된다
Entity 불러오기
guard let entity = NSEntityDescription.entity(forEntityName: "Car", in: context) else { return }
"Car" 이름의 entity를 불러왔다
Object 만들기
Object가 뭘까?
Core Data에서 Object란 모델 객체(Entity)의 인스턴스다
클래스를 만들고 클래스의 인스턴스를 만드는 것처럼 Entity로 Object를 만든다고 하면 될까?
let car = NSManagedObject(entity: entity, insertInto: context)
object를 만들었으니 object에 값도 넣어주자
car.setValue(myCar["brand"], forKey: "brand")
car.setValue(myCar["color"], forKey: "color")
car.setValue(myCar["price"], forKey: "price")
이제 저장하고자 하는 Object를 만들었으니, context를 통해 저장하면 된다
Context를 통해 저장하기
try? context.save()
전체 코드를 보면 아래와 같다
override func viewDidLoad() {
super.viewDidLoad()
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let context = appDelegate.persistentContainer.viewContext
guard let entity = NSEntityDescription.entity(forEntityName: "Car", in: context) else { return }
let car = NSManagedObject(entity: entity, insertInto: context)
car.setValue(myCar["brand"], forKey: "brand")
car.setValue(myCar["color"], forKey: "color")
car.setValue(myCar["price"], forKey: "price")
try? context.save()
}
데이터 불러오기
Entity 전체의 값을 불러오는 것은 아래와 같은 코드 한 줄이면 불러올 수 있다
let newcar = try? context.fetch(Car.fetchRequest())
print(type(of: newcar)) // Optional<Array<Car>>
print(newcar)
기본적인 저장과 불러오기 성공!
그런데, 저장하는 코드를 다 주석 처리한 후,
불러오는 코드만 둔 채 다시 run 하면 불러온 data의 값들이 다 fault로 나오는 걸 볼 수 있다
그럼 불러오기 코드를 다음과 같이 수정해 보자
let request = Car.fetchRequest()
request.returnsObjectsAsFaults = false
let newcar = try? context.fetch(request)
print(newcar)
해결!
Fault는 메모리에 완전히 올라오지 않은 object를 나타내는 placeHolder라고 한다 (faulting이라는 기술을 사용해서 메모리 사용 최소화)
returnsObjectsAsFaults 값은 true인 경우 NSFetchRequest를 사용해서 가져온 객체를 fault로 반환
기본값은 true인데, Core Data는 Object를 가져와서 row cache를 정보로 채우고, managed object를 faults로 반환한다
(이 부분은 다음에 더 자세하게 알아보자... TODO.......)
아니면 실제 값을 사용할 때에는 메모리에 올라오기 때문에 fault로 보이지 않는다
guard let newcar = try? context.fetch(Car.fetchRequest()) else { return }
newcar.forEach {
print($0.brand, $0.color, $0.price)
}
해결!
참고
https://zeddios.tistory.com/987
https://velog.io/@ssionii/Core-Data%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%84%EB%9D%BC%EB%B3%B4%EC%9E%90-3-Fetch-Data
https://developer.apple.com/documentation/coredata/nsfetchrequest/1506756-returnsobjectsasfaults
'programming > Swift' 카테고리의 다른 글
[Swift/iOS] 애플 로그인 후 반환 값 ASAuthorizationAppleIDCredential From 공식문서 (0) | 2023.05.06 |
---|---|
[Swift/iOS] CoreData 사용하기(4) - 속성값 유무에 따른 데이터 저장, 속성의 optional 타입 (0) | 2023.05.06 |
[Swift/iOS] CoreData 사용하기(2) - CoreData Stack 설정하기 From 공식문서 (0) | 2023.05.05 |
[Swift/iOS] CoreData 사용하기(1) - 프로젝트 중간에 추가하기, Entity 만들기 (0) | 2023.05.05 |
[Swift/iOS] 메모리 안전성 Memory Safety From 공식문서(2) (0) | 2023.05.05 |
- Total
- Today
- Yesterday
- 토큰저장
- ios
- Core Data Stack
- 디자인패턴
- unowned
- 강한참조순환
- 클로저
- Entity
- context
- SWIFT
- 메모리 안정성
- autoclosure
- ASAuthorizationAppleIDCredential
- 클로저 강한 참조
- object
- 회원가입
- 자동클로저
- weak
- CoreData
- escaping closrue
- identity Token
- 클로저 축약
- 캡쳐리스트
- Persistent Container
- inout 파라미터 메모리 충돌
- core data
- Delegate 패턴
- 클로저표현
- 강한 참조 순환
- authorizationCode
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |