소개: 왜 핵심 자료 및 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에 체크 아웃하십시오.