悲報:用了兩年多的筆電螢幕陣亡了。
外接螢幕倒是沒什麼問題,但是螢幕本體感覺完全掛了。是該花錢修好還是要轉型桌電QQ。
core data 是 iOS 用來儲存的框架,當中有 entity,attributes 和 relationships。我自己認為這比較適合用 object 的概念來理解,會有很多個 entity,每個 entity 可能有多種 attributes,而 entity 之間的關係則用 relation 來描述。
下面是 by Claude 老師的範例,CoreDataStack 通常包含幾個部分:
import CoreData
import Foundation
// MARK: - Core Data stack
class CoreDataStack {
static let shared = CoreDataStack()
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "BookModel")
container.loadPersistentStores { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
}
return container
}()
var context: NSManagedObjectContext {
return persistentContainer.viewContext
}
}
在下面的 CoreDataStack 中,NSPersistentContainer 不一定會直接寫到 NSPersistentStoreCoordinator 和 NSManagedObjectModel 這兩個東西,但這塊會被自動處理,也可以透過 .persistentStoreCoordinator 和 .managedObjectModel 去曝露出來,就像以下內容:
import CoreData
import Foundation
// MARK: - Core Data stack
class CoreDataStack {
// ...
var persistentStoreCoordinator: NSPersistentStoreCoordinator {
return persistentContainer.persistentStoreCoordinator
}
var managedObjectModel: NSManagedObjectModel {
return persistentContainer.managedObjectModel
}
}
而 NSManagedObjectContext 包含 viewContext 和 backgroundContext,差別是 viewContext 會用在 main thread 上,background context 則用在 bg thread 上,可以考量到需要操作時改動到的資料量大小而決定要在哪邊執行。
實際的操作例子如下(created by Claude):
// MARK: - Book Entity
class Book: NSManagedObject {
@NSManaged var title: String
@NSManaged var author: String
@NSManaged var year: Int16
}
// MARK: - CRUD Operations
class BookStore {
let context: NSManagedObjectContext
init() {
self.context = CoreDataStack.shared.context
}
// Create
func createBook(title: String, author: String, year: Int16) {
let book = Book(context: context)
book.title = title
book.author = author
book.year = year
do {
try context.save()
} catch {
print("Failed to save book: \(error)")
}
}
// Read
func fetchAllBooks() -> [Book] {
let fetchRequest: NSFetchRequest<Book> = Book.fetchRequest()
do {
let books = try context.fetch(fetchRequest)
return books
} catch {
print("Failed to fetch books: \(error)")
return []
}
}
// Update
func updateBook(book: Book, newTitle: String?, newAuthor: String?, newYear: Int16?) {
if let title = newTitle {
book.title = title
}
if let author = newAuthor {
book.author = author
}
if let year = newYear {
book.year = year
}
do {
try context.save()
} catch {
print("Failed to update book: \(error)")
}
}
// Delete
func deleteBook(book: Book) {
context.delete(book)
do {
try context.save()
} catch {
print("Failed to delete book: \(error)")
}
}
}
// Usage example
let bookStore = BookStore()
// Create books
bookStore.createBook(title: "1984", author: "George Orwell", year: 1949)
bookStore.createBook(title: "To Kill a Mockingbird", author: "Harper Lee", year: 1960)
// Fetch and print all books
let allBooks = bookStore.fetchAllBooks()
// Update a book
if let bookToUpdate = allBooks.first {
bookStore.updateBook(book: bookToUpdate, newTitle: nil, newAuthor: nil, newYear: 1950)
print("Updated book: \(bookToUpdate.title), Year: \(bookToUpdate.year)")
}
// Delete a book
if let bookToDelete = allBooks.last {
bookStore.deleteBook(book: bookToDelete)
}
// Fetch and print all books again to see the changes
let updatedBooks = bookStore.fetchAllBooks()
for book in updatedBooks {
print("Title: \(book.title), Author: \(book.author), Year: \(book.year)")
}