Table of Contents
소개: 왜 핵심 자료 및 NSFetchedResultsController 매트
이 웹 사이트는 애플 리케이션에 전념. 우리는 정품 앱과 게임을 제공 할 목적으로이 사이트를 만들었습니다. 4AppsApk 최고의 안드로이드 애플 리케이션을위한 무료 APK 파일 다운로드 서비스, 계략.
이 문서는 Core Data를 사용하여 심층적, 실용적인 가이드를 제공합니다 알림은 키입니다. 개체가 삽입되면 업데이트, 삭제, 수정된 상태는 이러한 변경 사항을 정확하게 방송합니다. ]]는 UI를 일관성 있게 유지하도록 레버리지.
공식 개발자 문서의 경우 ]Apple의 Core Data Framework Reference]를 참조하세요.
NSFetchedResultsController: 핵심 자료와 당신의 UI 사이 교량
는 Core Data fetch 요청에서, 특히 데이터를 변경할 것으로 예상되는 경우, 결과를 효율적으로 관리하도록 설계된 컨트롤러 객체입니다. 이 기능은 관련 관리 객체 컨텍스트를 모니터링하고 디플게이트 프로토콜을 통해 자동으로 변경 사항을 보고합니다.
핵심 특징
- 자동 변경 추적: FRC는 컨텍스트 알림을 듣고 구조화 된 delegate 콜백으로 번역합니다 (], , ]).
- Built-in sectioning: 를 지정함으로써, 컨트롤러 그룹 fetch 결과가 섹션에 표시된 테이블 레이아웃이나 컬렉션 보기에 트리 바이알을 만드는.
- Performance 최적화: FRC는 잘못된 사용과 후드 아래에 캐싱. 필요한 만큼의 태치 데이터만 사용하며, 관리된 객체 컨텍스트가 저장될 때 재-fetching을 방지하기 위해 지속적 캐시를 사용할 수 있습니다.
Delegate 방법
컨트롤러에서 완전히 혜택을 얻으려면 ]을 구현해야합니다. 가장 일반적인 패턴은 ] 또는 ]]]에서 UI를 일괄 업데이트하는 데 사용됩니다. 예를 들어:
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.beginUpdates()
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>,
didChange anObject: Any,
at indexPath: IndexPath?,
for type: NSFetchedResultsChangeType,
newIndexPath: IndexPath?) {
switch type {
case .insert:
tableView.insertRows(at: [newIndexPath!], with: .fade)
case .delete:
tableView.deleteRows(at: [indexPath!], with: .fade)
case .update:
tableView.reloadRows(at: [indexPath!], with: .fade)
case .move:
tableView.moveRow(at: indexPath!, to: newIndexPath!)
@unknown default:
tableView.reloadData()
}
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.endUpdates()
}
이 패턴은 테이블보기는 밑으로 데이터와 동기화의 변화를 확인하고, 흔들림이나 일관성을 방지합니다.
Step-by-Step 구현
아래는 Swift 5를 사용하여 전체 생산 읽기 예입니다. iOS 15 +를 대상으로합니다. 우리는 ] 속성 ] (String) 및 (Bool) 및 (Date)와 같은 간단한 법인을 가정합니다.
1. Core Data Stack 설정
또는 전용 ] ( SwiftUI 앱에서 사용), 지속적인 컨테이너를 만듭니다.
class PersistenceController {
static let shared = PersistenceController()
let container: NSPersistentContainer
init() {
container = NSPersistentContainer(name: "YourModelName")
container.loadPersistentStores { storeDescription, error in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
}
container.viewContext.automaticallyMergesChangesFromParent = true
}
}
2. NSManagedObject Subclass를 생성
Xcode의 데이터 모델 편집기를 사용하여 클래스 파일을 생성하거나 수동으로 만들 수 있습니다. 엔티티티티를 사용하여 올바른 클래스 모듈 설정을 사용합니다.
3. Fetch Request 및 FRC 구성
보기 컨트롤러에서 fetch 요청을 설정하고 fetched 결과 컨트롤러를 초기화합니다. 이것은 또는 전망 모델의 init에서 이것을 수행하는 것이 가장 좋습니다.
lazy var fetchedResultsController: NSFetchedResultsController<Task> = {
let fetchRequest: NSFetchRequest<Task> = Task.fetchRequest()
let sortDescriptor = NSSortDescriptor(key: "dueDate", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
// Optional: limit results with batch size for large datasets
fetchRequest.fetchBatchSize = 20
let controller = NSFetchedResultsController(
fetchRequest: fetchRequest,
managedObjectContext: PersistenceController.shared.container.viewContext,
sectionNameKeyPath: "completionStatus", // e.g., a transient attribute or a computed property
cacheName: nil
)
controller.delegate = self
try? controller.performFetch()
return controller
}()
4. 테이블보기를 FRC로 구동
당신의 방법은 삼관이된다 :
func numberOfSections(in tableView: UITableView) -> Int {
fetchedResultsController.sections?.count ?? 0
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let sectionInfo = fetchedResultsController.sections![section]
return sectionInfo.numberOfObjects
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TaskCell", for: indexPath)
let task = fetchedResultsController.object(at: indexPath)
configure(cell, with: task)
return cell
}
공지 우리는 수동으로 호출하지 않습니다 - delegate 방법 모든 삽입, 삭제 및 업데이트 처리.
고급 사용 및 모범 사례
실 안전
Core Data contexts는 스레드 안전하지 않습니다. 항상 ] (주요 큐에 실행) 모든 UI 관련 fetch 요청 및 FRCs를 사용합니다. 배경 작업을 위해 개인 큐 컨텍스트를 만들고 보기 컨텍스트로 변경을 만듭니다. 여러 큐에 걸쳐 동일한 FRC를 사용하지 마십시오.
뚱 베어
매개변수는 persisting section and object info로 실행 성능을 향상시킬 수 있습니다. 그러나 fetch request나 data model changes를 한다면, corruption을 피하기 위해 캐시 (]])를 삭제해야 합니다.
대용량 Datasets 처리
]를 사용하여 메모리에 붙인 객체의 수를 제한합니다. 또한, 모든 속성에 즉시 액세스 할 필요가있는 경우 ]를 설정 고려하십시오. 관계 집중 데이터의 경우 로 사전 태핑하면 반복 된 결함을 방지 할 수 있습니다.
SwiftUI와 통합
는 UIKit-centric이지만, ]에서 감싸거나 더 새로운 ] 속성 래퍼 (내부적으로 유사한 메커니즘을 사용)을 사용하여 SwiftUI에서 여전히 사용할 수 있습니다. SwiftUI의 복잡한 동적 데이터의 경우 는 일반적으로 충분하지만 FRC는 애니메이션과 배치에 대한 미세 횡단 제어를 제공합니다.
일반적인 Pitfalls 및 Them을 방지하는 방법
- ]:] 컨트롤러는 이 메소드를 호출할 때까지 fetch를 실행하지 않습니다. 일단, 일반적으로 초기화 후 오른쪽으로.
- ] delegate를 설정하지 않습니다:] delegate없이, 변경 테이블보기에 propagate하지 않을 것입니다. 항상 을 호출합니다.
- Incorrect sort descriptors: 의 섹션 이름 키 경로가 첫 번째 정렬 디코더와 일치하지 않는 경우, 섹션은 순서대로 나타날 수 있습니다. ]에서 사용되는 속성은 정렬 디코더에 나타납니다.
- FRC:]] 를 사용해서 ] 호출 ] FRC는 변경이 충돌을 일으킬 수 있는 동안. delegate 메소드를 모든 UI 업데이트를 처리할 수 있습니다.
- 핵심 데이터 컨텍스트를 무시하면 실패를 구합니다: 만약 상황에 맞는 오류가 발생하면, FRC는 통보되지 않을 수 있습니다. 항상 오류를 처리하고 배경 상황에 ]를 고려하십시오.
성능 고려
은 이미 효율적이지만, 여기에는 추가 최적화가 있습니다.
- 은 현명하게 사용: 복잡한 사전은 초기 fetch를 느리게 할 수 있습니다. 가능한 한 인덱스된 속성을 사용합니다.
- Limit fetched 속성:] 만약 당신이 특정 속성을 필요로 하는 경우, ] 을 fetch 요청에.
- Batch 업데이트: 많은 변경을 할 때, ] 블록에서 delegate 콜백의 번호를 감소.
- Avoid 불필요한 오류:] 결과 설정에서 모든 개체에 액세스 할 수 있다면, 를 사용하여, 메모리에주의해야합니다.
Core Data 성능에 더 깊은 다이빙을 위해 ]Apple의 Core Data Performance Guide]를 참조하십시오.
Real-World 예제
예 1: 채팅 신청
메시징 앱은 최근 메시지로 분류된 대화 목록을 표시합니다. 새로운 수신 메시지는 즉시 나타납니다. FRC를 사용하여 연락처 보기는 현재 사용자의 대화 엔티티만에만 변경할 수 있습니다. 날짜 그룹 메시지에 의해 "오늘", "어제일", 등.
예 2: Inventory 관리
전자 상거래 앱은 카테고리에서 제품을 보여줍니다. 재고 수준이 배경 동기화에서 변경할 때, FRC는 UI를 자동으로 업데이트합니다. 에서 50으로 설정하면 수천 개의 항목과도 응답 할 수 있습니다.
예 3: 카테고리로 목록
고전적인 예: "Overdue", "Today", "Upcoming"으로 그룹화 된 작업. ]은 ]] 및 현재 날짜에서 계산 된 일시적인 파생 된 속성이 될 수 있습니다. 동일한 파생 된 값은 mismatches를 피하기 위해 정렬 descriptor에서 사용됩니다.
관련 기사
Core Data와 의 조합을 마스터하면 견고한 동적 iOS 애플리케이션을 구축하는 코너스톤입니다. 변경 추적 및 UI 동기화의 무거운 리프팅을 해제하면, 보일러판 데이터 관리 코드보다 큰 사용자 경험을 만드는 데 집중할 수 있습니다.
레거시 UIKit 앱을 유지하거나 ]을 사용하여 SwiftUI를 채택하는 것은 원칙이 동일하게 유지됩니다. 객체 그래프를 이해하고, 신중하게 fetch 요청을 구성하고, fetched results Controller가 가장 잘 작동하는지 확인하십시오. 이 문서에서 실행되는 관행으로 - 캐싱, 실 안전 및 성능 조정을 포함하여 - 시간이 지나면 진화하는 모든 데이터 세트를 처리 할 수 있습니다.
더 탐험을 위해 ]Ray Wenderlich의 핵심 데이터 자습서 및 NSHipster 기사 NSFetchedResultsController에 체크 아웃하십시오.