• Feed
  • Explore
  • Ranking
/
/
    📱 iOS

    [iOS] NSFetchedResultsController를 활용한 성능 최적화

    Swiftios
    지
    지성
    2025.02.19
    ·
    3 min read

    Core Data에서 데이터를 효율적으로 불러오고 UI와 동기화하려면 NSFetchedResultsController를 활용해야 한다.

    특히 UITableView 및 UICollectionView와 함께 사용할 때 성능 최적화에 큰 도움이 된다.


    문제 상황

    Core Data에서 데이터를 불러와 UITableView에 표시할 때 성능 저하 문제가 발생했다.

    1. fetchRequest를 매번 실행하면 데이터가 많아질수록 로딩 속도가 느려진다.

    2. 데이터 변경 시 UI가 자동으로 업데이트되지 않는다.

    3. tableView.reloadData()를 자주 호출하면 불필요한 렌더링으로 성능 저하가 발생한다.

    해결 방안

    1. NSFetchedResultsController 설정

      • Core Data에서 NSFetchedResultsController를 사용하면, 데이터가 변경될 때 자동으로 UI를 업데이트할 수 있고 불필요한 reloadData() 호출 없이 성능 최적화가 가능하다.

        import CoreData
        
        class MyDataManager: NSObject, NSFetchedResultsControllerDelegate {
            static let shared = MyDataManager()
        
            private var fetchedResultsController: NSFetchedResultsController<MyEntity>!
        
            lazy var persistentContainer: NSPersistentContainer = {
                let container = NSPersistentContainer(name: "MyAppModel")
                container.loadPersistentStores { _, error in
                    if let error = error {
                        fatalError("Core Data error: \(error)")
                    }
                }
                return container
            }()
        
            private var context: NSManagedObjectContext {
                return persistentContainer.viewContext
            }
        
            override init() {
                super.init()
                setupFetchedResultsController()
            }
        
            private func setupFetchedResultsController() {
                let fetchRequest: NSFetchRequest<MyEntity> = MyEntity.fetchRequest()
                fetchRequest.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
                fetchRequest.fetchBatchSize = 20  // 한 번에 가져올 데이터 개수 제한 (성능 최적화)
        
                fetchedResultsController = NSFetchedResultsController(
                    fetchRequest: fetchRequest,
                    managedObjectContext: context,
                    sectionNameKeyPath: nil,
                    cacheName: nil
                )
                fetchedResultsController.delegate = self
        
                do {
                    try fetchedResultsController.performFetch()
                } catch {
                    print("Fetch error: \(error.localizedDescription)")
                }
            }
        
            func getFetchedResultsController() -> NSFetchedResultsController<MyEntity> {
                return fetchedResultsController
            }
        }
    2. UITableView와 자동 동기화

      • 데이터가 변경되면 NSFetchedResultsControllerDelegate를 통해 자동으로 UI 업데이트가 가능하다.

        extension MyViewController: NSFetchedResultsControllerDelegate {
            func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
                tableView.reloadData()
            }
        }






    - 컬렉션 아티클