Swift Alamofire回调导致数据库多线程访问错误
Swift Alamofire callback causes database multithread access error
我正在使用 Alamofire.upload,在 encodingCompletion 回调中我想更新数据库。
我为每个数据库访问使用 DBManager.shared.database 连接,但这似乎会导致问题,因为我得到异常,多个线程尝试同时使用相同的连接。
是否有一些关于如何使用回调来防止此类问题的指南?
我将为您提供一些使用 Alamofire 发布数据的示例代码。我希望它易于理解并有所帮助。如果有什么不清楚的地方,请告诉我。
func addProduct(token:String,product:Product, completion:@escaping( Error? )->Void)
{
let addProductHeader:HTTPHeaders = [
"token":"\(token)",
"Accept":"application/json"
]
let addProductParameter:Parameters = [
"name" : "\(product.name!)",
"manufacture" : "\(product.manufacture!)",
"description" : "\(product.descriptionField!)",
"amount" : product.amount!,
"quantity" : product.quantity!,
"date" : "\(product.date!)"
]
AF.request("Enter Your Server DB Link Here", method: .post, parameters: addProductParameter, encoding: JSONEncoding.default, headers: addProductHeader).responseJSON
{
(response) in
let encode = JSONEncoder()
encode.outputFormatting = .prettyPrinted
do
{
let jsonData = try encode.encode(product)
print(jsonData)
if let jsonString = String(data: jsonData, encoding: .utf8)
{
print(jsonString)
}
completion( nil )
}
catch
{
print(error.localizedDescription)
completion(error)
}
}
}
听起来您需要同步数据库访问。在数据库单例旁边创建静态 DispatchQueue
并通过该队列分派所有数据库访问的最简单方法。
编辑:类似于:
final class DBManager {
static let shared = DBManager()
static let queue = DispatchQueue(label: "your.identifier.here.DBManagerQueue")
}
像这样使用它:
... in a completion handler far far away ...
{ response in
DBManager.queue.async {
// Do something with the database
}
}
但是,更好的解决方案是将所有这些队列置于您的 DBManager
内部,以便它的所有用户始终是线程安全的。在您可以执行此类重构之前,这只是一个权宜之计。
我正在使用 Alamofire.upload,在 encodingCompletion 回调中我想更新数据库。
我为每个数据库访问使用 DBManager.shared.database 连接,但这似乎会导致问题,因为我得到异常,多个线程尝试同时使用相同的连接。
是否有一些关于如何使用回调来防止此类问题的指南?
我将为您提供一些使用 Alamofire 发布数据的示例代码。我希望它易于理解并有所帮助。如果有什么不清楚的地方,请告诉我。
func addProduct(token:String,product:Product, completion:@escaping( Error? )->Void)
{
let addProductHeader:HTTPHeaders = [
"token":"\(token)",
"Accept":"application/json"
]
let addProductParameter:Parameters = [
"name" : "\(product.name!)",
"manufacture" : "\(product.manufacture!)",
"description" : "\(product.descriptionField!)",
"amount" : product.amount!,
"quantity" : product.quantity!,
"date" : "\(product.date!)"
]
AF.request("Enter Your Server DB Link Here", method: .post, parameters: addProductParameter, encoding: JSONEncoding.default, headers: addProductHeader).responseJSON
{
(response) in
let encode = JSONEncoder()
encode.outputFormatting = .prettyPrinted
do
{
let jsonData = try encode.encode(product)
print(jsonData)
if let jsonString = String(data: jsonData, encoding: .utf8)
{
print(jsonString)
}
completion( nil )
}
catch
{
print(error.localizedDescription)
completion(error)
}
}
}
听起来您需要同步数据库访问。在数据库单例旁边创建静态 DispatchQueue
并通过该队列分派所有数据库访问的最简单方法。
编辑:类似于:
final class DBManager {
static let shared = DBManager()
static let queue = DispatchQueue(label: "your.identifier.here.DBManagerQueue")
}
像这样使用它:
... in a completion handler far far away ...
{ response in
DBManager.queue.async {
// Do something with the database
}
}
但是,更好的解决方案是将所有这些队列置于您的 DBManager
内部,以便它的所有用户始终是线程安全的。在您可以执行此类重构之前,这只是一个权宜之计。