初始化Core Data上下文报错:如何修复‘self.context未初始化即使用’问题
问题原因与解决方案
错误根源
@UIApplicationDelegateAdaptor 是SwiftUI用于注入AppDelegate的属性包装器,它的初始化时机晚于结构体的init方法。你在init里直接访问appDelegate时,这个实例还未完成初始化,导致赋值context时触发"Variable 'self.context' used before being initialized"错误。此外,你的MyView未遵守SwiftUI的View协议,缺少必要的body属性,这也是不符合SwiftUI视图规范的问题。
修正方案一:直接在方法内获取上下文
不需要提前存储context属性,在需要使用的方法里直接访问appDelegate的上下文即可:
import Foundation import SwiftUI import UIKit import CoreData // 必须遵守View协议并实现body struct MyView: View { @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate var body: some View { VStack { Button("保存股票数组") { createStock(stockArray: ["AAPL", "GOOG", "MSFT"]) } Button("获取股票数据") { let stocks = fetchStocks() print(stocks) } } } func createStock(stockArray: [String]) { let context = appDelegate.persistentContainer.viewContext let newStock = Stock(context: context) // 注意:Core Data中存储数组需将stockArr设为Transformable类型,自定义类选[String] newStock.stockArr = stockArray as NSObject do { try context.save() } catch { print("保存Stock失败: \(error.localizedDescription)") } } func fetchStocks() -> [Stock] { let context = appDelegate.persistentContainer.viewContext let fetchRequest: NSFetchRequest<Stock> = Stock.fetchRequest() do { let stocks = try context.fetch(fetchRequest) return stocks } catch { print("获取Stock失败: \(error.localizedDescription)") return [] } } }
修正方案二:使用SwiftUI推荐的Environment注入上下文
这是Core Data在SwiftUI中更标准的用法,无需依赖AppDelegate:
- 在App入口注入上下文:
@main struct YourApp: App { let persistenceController = PersistenceController.shared var body: some Scene { WindowGroup { MyView() .environment(\.managedObjectContext, persistenceController.container.viewContext) } } }
- 修改MyView直接通过Environment获取上下文:
import Foundation import SwiftUI import CoreData struct MyView: View { // 通过Environment直接获取上下文 @Environment(\.managedObjectContext) private var context var body: some View { VStack { Button("保存股票数组") { createStock(stockArray: ["AAPL", "GOOG", "MSFT"]) } Button("获取股票数据") { let stocks = fetchStocks() print(stocks) } } } func createStock(stockArray: [String]) { let newStock = Stock(context: context) newStock.stockArr = stockArray as NSObject do { try context.save() } catch { print("保存Stock失败: \(error.localizedDescription)") } } func fetchStocks() -> [Stock] { let fetchRequest: NSFetchRequest<Stock> = Stock.fetchRequest() do { let stocks = try context.fetch(fetchRequest) return stocks } catch { print("获取Stock失败: \(error.localizedDescription)") return [] } } }
额外注意事项
- 在Core Data模型编辑器中,需将
Stock实体的stockArr字段设置为Transformable类型,并在右侧检查器的Custom Class处选择[String],这样才能正确存储和读取字符串数组。 - 确保
Stock实体已在Core Data模型中正确创建,包含stockArr属性。
内容的提问来源于stack exchange,提问作者Ahmed Zaidan
相关产品推荐
相关产品推荐

