Core Data là một framework quản lý dữ liệu của Apple cung cấp ánh xạ đối tượng-quan hệ cho iOS, macOS, tvOS và watchOS. Nó tự động hóa việc lưu, truy xuất và lọc các đối tượng trong ứng dụng, hoạt động trên SQLite, XML hoặc bộ nhớ nhị phân. Theo Apple Core Data Documentation, framework sử dụng các khái niệm Managed Object Context và NSPersistentContainer để quản lý ngăn xếp lưu trữ bền vững.
Những điểm chính
Core Data là một framework quản lý đồ thị đối tượng và lưu trữ bền vững, là một phần của Cocoa Touch. Trái ngược với quan niệm sai lầm phổ biến, Core Data không phải là cơ sở dữ liệu, mà là một lớp quản lý đối tượng có thể sử dụng SQLite như một trong các kho lưu trữ. Nhiệm vụ chính của Core Data là theo dõi các thay đổi của đối tượng, quản lý vòng đời của chúng và đồng bộ hóa trạng thái với đĩa.
Framework cung cấp một đồ thị đối tượng nơi mỗi Managed Object được context theo dõi các thay đổi. Khi lưu, tất cả các đối tượng đã sửa đổi, thêm và xóa được cam kết vào kho lưu trữ bền vững trong một giao dịch duy nhất. Điều này loại bỏ nhu cầu nhà phát triển phải viết truy vấn SQL và quản lý giao dịch thủ công.
Theo thống kê của Swift Developer Survey (2025), Core Data được sử dụng trong 52% ứng dụng iOS làm việc với dữ liệu cục bộ. Mặc dù có sự xuất hiện của các giải pháp thay thế hiện đại (SwiftData, Realm), Core Data vẫn là framework chính trong các dự án Apple hiện có nhờ sự trưởng thành và tích hợp sâu với hệ thống.
Sử dụng Core Data cho các dự án có mô hình dữ liệu độ phức tạp trung bình, nơi cần có mối quan hệ giữa các đối tượng, hoàn tác thay đổi và bộ nhớ đệm tự động thông qua cơ chế faulting.
Kiến trúc Core Data được xây dựng xoay quanh khái niệm Managed Object Context — một không gian làm việc theo dõi tất cả các thay đổi của đối tượng. Context hỗ trợ hoàn tác/làm lại thông qua NSUndoManager tích hợp, cho phép triển khai bản nháp và hủy hành động mà không cần lưu ảnh chụp nhanh trạng thái thủ công. Khi gọi save(), context cam kết tất cả các thay đổi trong một giao dịch duy nhất vào kho lưu trữ bền vững, đảm bảo tính nguyên tử và nhất quán của dữ liệu.
Mô hình dữ liệu Core Data được định nghĩa trong tệp .xcdatamodeld — trình chỉnh sửa trực quan của Xcode nơi tất cả Entity, thuộc tính và mối quan hệ được mô tả. Khi biên dịch, mô hình được tuần tự hóa thành .momd và được tải qua NSManagedObjectModel.
Entity là mô tả kiểu dữ liệu, tương tự như một bảng trong SQL. Mỗi Entity chứa một tập hợp Attributes — các trường có tên với kiểu dữ liệu (String, Integer, Date, Boolean, Data). Không giống như Room, Core Data yêu cầu chọn kiểu rõ ràng cho mỗi thuộc tính thông qua trình chỉnh sửa mô hình.
Relationship là kết nối giữa các Entity, tương tự như khóa ngoại trong SQL. Core Data hỗ trợ tất cả các loại mối quan hệ: một-một, một-nhiều và nhiều-nhiều. Mỗi mối quan hệ có Delete Rule được cấu hình (Cascade, Nullify, Deny) — hành vi khi xóa đối tượng liên quan.
| Delete Rule | Hành vi khi xóa | Ví dụ sử dụng |
|---|---|---|
| Cascade | Xóa tất cả đối tượng liên quan | Xóa đơn hàng cùng với các mục |
| Nullify | Đặt mối quan hệ ngược thành null | Xóa tác giả mà không xóa sách |
| Deny | Chặn xóa nếu có đối tượng liên quan | Bảo vệ khỏi việc xóa danh mục có sản phẩm |
Chọn Delete Rule rất quan trọng đối với tính toàn vẹn dữ liệu: Cascade mà không kiểm tra có thể xóa một phần ba cơ sở dữ liệu, trong khi Deny có thể chặn hoạt động với lỗi không rõ ràng. Trong mã sản xuất, nên sử dụng Nullify với xử lý bản ghi mồ côi thủ công.
Trong trình chỉnh sửa mô hình Xcode, nhà phát triển có thể định nghĩa không chỉ Entity và thuộc tính, mà còn constraints (ràng buộc duy nhất), chỉ mục để tăng tốc truy vấn và giá trị mặc định cho thuộc tính. Tất cả các thay đổi mô hình được biên dịch thành tệp .momd, được tải trong quá trình khởi tạo NSPersistentContainer. Việc tạo phiên bản mô hình (Model Versioning) cho phép duy trì nhiều phiên bản lược đồ và thực hiện di chuyển giữa chúng.
NSPersistentContainer là một đối tượng duy nhất quản lý ngăn xếp Core Data từ iOS 10 và macOS 10.12. Nó đóng gói NSManagedObjectModel, NSPersistentStoreCoordinator và NSManagedObjectContext, tự động hóa việc tải mô hình và cấu hình kho lưu trữ. Đối với các phiên bản cũ hơn, ngăn xếp được xây dựng thủ công, nhưng điều này không còn được khuyến nghị.
let container = NSPersistentContainer(name: "DataModel")
container.loadPersistentStores { _, error in
if let error { fatalError("Core Data load failed: \(error)") }
}
let context = container.viewContext
viewContext là context chính gắn với luồng chính. Tất cả các lần đọc và cập nhật UI được thực hiện thông qua nó. Để có hiệu suất, nên thực hiện ghi dữ liệu trên context con nền với đồng bộ hóa sau đó.
Bộ điều phối NSPersistentStoreCoordinator kết nối mô hình với bộ nhớ vật lý trên đĩa. Core Data hỗ trợ nhiều loại kho lưu trữ: SQLite (khuyến nghị), Binary và In-Memory. Kho lưu trữ SQLite hỗ trợ di chuyển, sao lưu gia tăng và khả năng chống sự cố trong quá trình ghi.
NSFetchRequest là một đối tượng mô tả truy vấn đến kho lưu trữ Core Data. Nó chứa tên Entity, vị từ lọc, bộ mô tả sắp xếp và cài đặt tìm nạp. Truy vấn được thực thi qua context.fetch(), trả về một mảng NSManagedObject.
let request = NSFetchRequest<User>(entityName: "User")
request.predicate = NSPredicate(format: "age >= %d", 18)
request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
request.fetchLimit = 50
let results = try context.fetch(request)
NSPredicate hỗ trợ các điều kiện phức tạp: LIKE, IN, BETWEEN, CONTAINS[c] (không phân biệt hoa thường), SUBQUERY cho truy vấn lồng nhau trên Entity liên quan. Core Data cũng hỗ trợ NSFetchedResultsController — một lớp để tải dữ liệu phản ứng trong UITableView, tự động theo dõi các thay đổi và cập nhật bảng với các phần được hoạt ảnh.
Làm việc với Core Data trong ứng dụng đa luồng yêu cầu tuân thủ nghiêm ngặt các quy tắc: NSManagedObject không thể được truyền trực tiếp giữa các luồng. Mỗi luồng (hoặc hàng đợi) phải sử dụng context riêng của nó. Cách tiếp cận chính là tạo NSManagedObjectContext con với hàng đợi riêng (NSPrivateQueueConcurrencyType) để ghi và viewContext để đọc.
Context con lưu vào context cha, sau đó context cha lưu vào kho lưu trữ đĩa. Điều này đảm bảo rằng các thay đổi không chặn luồng chính và UI luôn thấy trạng thái nhất quán thông qua mergeChanges hoặc cập nhật viewContext tự động khi lưu.
Core Data sử dụng faulting — một cơ chế tải chậm cho các đối tượng liên quan. Khi tìm nạp User mà không yêu cầu địa chỉ của họ, các đối tượng Address liên quan không được tải cho đến khi chúng được truy cập qua ký hiệu dấu chấm. Faulting tiết kiệm bộ nhớ và tăng tốc tải, nhưng có thể gây ra truy cập đĩa không mong muốn trên luồng chính nếu không kiểm soát truy cập trong các context nền.
Để đa luồng hiệu quả, hãy sử dụng NSBatchInsertRequest và NSBatchDeleteRequest để chèn và xóa hàng loạt mà không tải đối tượng vào bộ nhớ — điều này rất quan trọng để đồng bộ hóa dữ liệu với máy chủ.
Các thao tác hàng loạt thực thi trực tiếp ở cấp NSPersistentStoreCoordinator, bỏ qua context và đồ thị đối tượng. Điều này cho phép chèn 10.000 bản ghi trong mili giây mà không tạo 10.000 phiên bản NSManagedObject trong bộ nhớ. Sau khi thực hiện yêu cầu hàng loạt, context phải được cập nhật qua mergeChangesFromContextDidSaveNotification để UI phản ánh dữ liệu mới. Apple khuyến nghị các thao tác hàng loạt cho việc tải dữ liệu ban đầu và đồng bộ hóa qua đêm với máy chủ.
Để theo dõi thay đổi trong Core Data, NSPersistentHistoryTracking được sử dụng — một cơ chế ghi lại mỗi giao dịch (chèn, cập nhật, xóa) trong một lịch sử riêng biệt. Bật theo dõi lịch sử cho phép đồng bộ hóa dữ liệu giữa các tiến trình và ứng dụng khác nhau làm việc với cùng một tệp SQLite, ví dụ giữa ứng dụng chính và Notification Service Extension. Kích hoạt được thực hiện qua NSPersistentStoreDescription với cờ persistentHistoryTrackingKey, và đọc qua NSPersistentHistoryChangeRequest với lọc theo ngày và loại giao dịch.
Để gỡ lỗi và phân tích hiệu suất Core Data, công cụ Core Data Profiler từ bộ Instruments trong Xcode trên macOS được sử dụng. Nó hiển thị tất cả các thao tác tìm nạp, chèn, xóa và lưu với thời lượng của mỗi thao tác và số lượng đối tượng được tải trong các bảng và biểu đồ dòng thời gian. Nhà phát triển có thể xác định các khu vực có vấn đề: nhiều lần tìm nạp cùng một truy vấn (thiếu bộ nhớ đệm), rò rỉ đối tượng fault khi cuộn bảng hoặc chặn luồng chính do tải đồng bộ các thực thể liên quan. Nên chạy hồ sơ trên thiết bị thực chứ không phải trên trình mô phỏng, vì hiệu suất của trình mô phỏng không phản ánh hành vi thực tế của ứng dụng trên iPhone hoặc iPad.
Câu hỏi thường gặp
Core Data không phải là cơ sở dữ liệu, mà là một lớp quản lý đối tượng có thể sử dụng SQLite làm kho lưu trữ. Không giống như SQLite trực tiếp, Core Data theo dõi các thay đổi đối tượng, quản lý hoàn tác và cung cấp đồ thị đối tượng với faulting và bộ nhớ đệm. SQLite cung cấp nhiều quyền kiểm soát hơn đối với các truy vấn, nhưng yêu cầu viết SQL và quản lý giao dịch thủ công.
Core Data hỗ trợ di chuyển nhẹ (Lightweight Migration) cho các thay đổi không phá hủy: thêm thuộc tính, đổi tên, đặt giá trị mặc định. Đối với các thay đổi phức tạp, Mapping Model được tạo. Di chuyển nhẹ được bật bằng cờ shouldMigrateAutomatically trong NSPersistentStoreDescription.
Có, Core Data tích hợp với SwiftUI qua wrapper @FetchRequest cho các truy vấn và @ObservedObject để đăng ký thay đổi. SwiftUI tự động cập nhật View khi ManagedObject thay đổi, làm cho Core Data và SwiftUI trở thành một ngăn xếp tương thích để quản lý trạng thái.
Fault là một trình giữ chỗ nhẹ trong đồ thị Core Data không chứa dữ liệu của đối tượng liên quan. Khi fault được đặt (qua refreshObject:), dữ liệu được giải phóng khỏi bộ nhớ. Khi truy cập vào một thuộc tính, fault tự động được điền dữ liệu từ kho lưu trữ — đây là cơ chế tải chậm tối ưu hóa việc sử dụng bộ nhớ.
Để kiểm tra, hãy sử dụng loại kho lưu trữ In-Memory: NSPersistentStoreDescription với NSInMemoryStoreType. Container được tạo với mô hình từ gói kiểm tra. Sau mỗi bài kiểm tra, xóa tất cả đối tượng hoặc tạo lại container — điều này đảm bảo sự cách ly giữa các trường hợp kiểm tra với nhau.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm