面试题答案
一键面试实现方法
- 使用
@FetchRequest
和ObservableObject
:@FetchRequest
用于从Core Data获取数据,并自动监听数据变化。当Core Data中的数据发生改变时,SwiftUI视图会自动重新渲染。ObservableObject
用于定义数据模型,并且通过@Published
属性包装器标记需要监听变化的属性。
- 使用
NSFetchedResultsController
(在UIKit和SwiftUI混合场景或更复杂场景下也常用):它可以监控Core Data数据的变化,并提供一种机制来更新UI。在SwiftUI中可以将其与ObservableObject
结合使用。 - 使用
NotificationCenter
:Core Data会发布一些通知,例如NSManagedObjectContextDidSave
通知,我们可以监听这些通知,在数据保存后手动更新视图。
代码实现思路示例(以@FetchRequest
和ObservableObject
为例)
- 定义Core Data数据模型:
假设我们有一个简单的待办事项数据模型
TodoItem
,它有一个标题title
和一个完成状态isCompleted
。
import CoreData
@objc(TodoItem)
public class TodoItem: NSManagedObject {
@NSManaged public var title: String
@NSManaged public var isCompleted: Bool
}
- 创建视图模型:
import SwiftUI
import CoreData
class TodoViewModel: ObservableObject {
@Published var todoItems: [TodoItem] = []
let viewContext: NSManagedObjectContext
init(viewContext: NSManagedObjectContext) {
self.viewContext = viewContext
fetchTodoItems()
}
func fetchTodoItems() {
let fetchRequest: NSFetchRequest<TodoItem> = TodoItem.fetchRequest()
do {
todoItems = try viewContext.fetch(fetchRequest)
} catch {
print("Error fetching todo items: \(error)")
}
}
func updateTodoItem(_ item: TodoItem, isCompleted: Bool) {
item.isCompleted = isCompleted
do {
try viewContext.save()
fetchTodoItems()
} catch {
print("Error saving changes: \(error)")
}
}
}
- 创建视图:
struct TodoListView: View {
@ObservedObject var viewModel: TodoViewModel
var body: some View {
List(viewModel.todoItems) { item in
HStack {
Toggle(isOn: Binding(get: { item.isCompleted }, set: { self.viewModel.updateTodoItem(item, isCompleted: $0) })) {
Text(item.title)
}
}
}
}
}
- 在
SceneDelegate
中设置上下文并展示视图:
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
let viewContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let viewModel = TodoViewModel(viewContext: viewContext)
let contentView = TodoListView(viewModel: viewModel)
self.window = UIWindow(windowScene: windowScene)
self.window?.rootViewController = UIHostingController(rootView: contentView)
self.window?.makeKeyAndVisible()
}
}
在上述代码中,TodoViewModel
通过@Published
属性todoItems
来监听待办事项数据的变化。当一个视图更新了待办事项的isCompleted
状态并保存到Core Data后,fetchTodoItems
方法会重新获取数据,触发@Published
属性的变化,从而使SwiftUI视图自动更新,保证了多个视图间数据的一致性。