swift - Swift:核心数据的线程问题
问题描述
我有一个应用程序,我在其中调用端点以从 API 检索产品列表:
var productList = [Product]
private func retrieveProducts() {
API.client.call(.products, expecting: [Product].self) { (result, products) in
switch result {
case .failure:
print("Unable to retrieve products")
case .success:
guard let productResponse = products else { return }
for product in productResponse {
productList.append(product)
}
}
}
}
注意:我们为 API 调用使用了一个辅助类,.products 注入了正确的 url。
产品类别:
class Product: Codable {
let id: String
let name: String?
}
然后使用这些产品来填充下拉列表。现在我要做的是让这些离线可用,所以基本上第一次启动应用程序时我想将产品保存到核心数据,然后在后续启动时我们只检索存储的列表。
因此,我使用名为 ProductCD 的实体构建了一个核心数据模型,并将我的 retrieveProducts 方法更改如下:
private func saveProductsToCD() {
API.client.call(.products, expecting: [Product].self) { (result, products) in
switch result {
case .failure:
print("Unable to retrieve products")
case .success:
guard let productResponse = products else { return }
for product in productResponse {
product.mapToCoreData()
}
DispatchQueue.main.async {
self.appDelegate.saveContext()
self.getSavedProducts()
}
}
}
}
internal func getSavedProducts() {
// First I attempt to retrieve the list from core data
let context = appDelegate.persistentContainer.viewContext
let request: NSFetchRequest<ProductCD> = ProductCD.fetchRequest()
do {
productsList = try context.fetch(request)
} catch {
print("Error fetching data from context \(error)")
}
// If no data available in core data I call the method above to hit the
// products endpoint and save to core data, then I retrieve the products
if productList.count == 0 {
self.saveProductsToCD()
}
}
我在 Product 类上添加了 mapToCoreData 方法:
class Product: Codable {
let id: String
let name: String?
internal func mapToCoreData() {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let storedProduct = ProductCD(context: context)
storedProduct.id = self.id
storedProduct.name = self.name ?? ""
}
}
因此,虽然这是一种工作,但存在问题。数据正在被存储和调用,但是由于线程问题(我猜)我收到了警告和一些偶尔的崩溃:
1-警告:在我的产品类中,我收到以下警告:
UIApplication.delegate must be used from main thread only
我尝试将调用包装在 DispatchQueue.Main.async 中,但我仍然收到消息。
2-有时在加载时,我的应用程序崩溃并显示以下消息:
Thread 9: EXC_BAD_ACCESS (code=1, address=0x0)
在我的产品类的这一行:
let storedProduct = ProductCD(context: context)
当我在本质上试图检索核心数据库的文本字段中键入时,会发生此错误。
此崩溃仅在启动时偶尔发生,因此我确定这是线程问题,但不确定如何解决。
解决方案
推荐阅读
- r - 物料需求计划包
- python - 使用自定义变压器时如何正确腌制sklearn管道
- python - 如何在删除网格线后将图表边框角更改为圆形并更改 Excel 工作表背景的颜色
- uibutton - UIButton width doesn't increase based on text if insets are given
- laravel - Laravel 6.0 app.js 只有 require('.bootstrap');?
- spring - 在 SpringBoot 控制器中接收/发送 MultiRow 数据以及文件
- java - 当我想从 neo4j 获取一些数据时,我总是得到 null
- ansible - 将文件从ansible中的相对路径复制到服务器
- postgresql - PostgreSQL中的行级锁定是原子的吗?
- angular - 如何在 mat-slide-toggle 中添加“开”、“关”标签?