gpt4 book ai didi

ios - 完成处理程序无法按预期与 Dispatch Group 和 Concurrent Queue 一起工作

转载 作者:塔克拉玛干 更新时间:2023-11-02 10:26:15 26 4
gpt4 key购买 nike

我创建了一个 Dispatch 组,其中三个并发队列正在运行,然后通知组进行更新,这一切进展顺利,所有这些我都放在一个带有完成处理程序的函数中。现在我面临的问题是完成处理程序在队列执行完成之前被调用。我该如何解决这个问题,请指教?

   func loadCompaniesFromSynch(_ data: Data, completionHandler: @escaping(String) -> ())
{

var companyFile = ""
companies = [Company]()
let batchGroup = DispatchGroup()
let queue = DispatchQueue(label: "Batch Queue", qos: .background, attributes: .concurrent)

if !FileManager.default.fileExists(atPath: self.fileMgr.getDocumentPath()) {
self.fileMgr.createFileDirectory(self.constants!.APP_FOLDER)
}

companyFile = self.fileMgr.getDocumentFilePath(self.fileMgr.getCacheData(constants!.COMPANIES_LAST_SYNCH_DATE) as! String)
let dataOld: Data = try! Data(contentsOf: URL(fileURLWithPath: companyFile),options: NSData.ReadingOptions.uncached)

let oldCompanies: NSArray! = (try? JSONSerialization.jsonObject(with: dataOld, options: JSONSerialization.ReadingOptions.mutableContainers)) as? [[String:Any]] as NSArray!

let newCompanyObj: NSDictionary? = (try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers)) as? NSDictionary

var company: Company?

if newCompanyObj?.count > 0 {

if let companies = oldCompanies
{
for com in companies as! [[String: AnyObject]]
{

company = Company()
company!.orgCode = com["ORG_CODE"] as? String
company!.orgDescription = com["ORG_DESCRIPTION"] as? String

if let btlOrg = com["OBX_BTL_CODE"] as? String
{
company!.orgBtlCode = btlOrg
company!.orgBtlDescription = com["BTL_DESCRIPTION"] as? String
}
company!.orgStatus = com["ORG_STATUS"] as! String?

self.companies!.append(company!)
company = nil
}



}

print("loadCompaniesFromSynch >> oldCompanies >>\(oldCompanies.count) Comapnies Count \(self.companies!.count)")

var dataDict = Dictionary<String,String>()

if let json = newCompanyObj as NSDictionary!
{
if let companies = json["RESULTS"] as? NSDictionary
{
if let companiesNew = companies["COMPANIES"] as? [[String: AnyObject]]
{
// for com in companiesNew

let addArray = companiesNew.filter { $0["ORG_STATUS"] as! String == ComapnyStatus.ADD.rawValue}
let deleteArray = companiesNew.filter { $0["ORG_STATUS"] as! String == ComapnyStatus.DELETED.rawValue}
let updateArray = companiesNew.filter { $0["ORG_STATUS"] as! String == ComapnyStatus.UPDATE.rawValue}

print(addArray.count)
print(deleteArray.count)
print(updateArray.count)



var addCompanies: [Company]?
var updateCompanies:[Company]?
var comapnySet = Set(self.companies!)


batchGroup.enter()
queue.async(group: batchGroup)
{
if (addArray.count > 0 )
{
addCompanies = [Company]()
for (index,item) in addArray.enumerated()
{

let company = self.returnComapnyOjectfromDictionary(item as NSDictionary)
addCompanies!.append(company)
print("add loop----\(index)")
}

}
batchGroup.leave()

}

batchGroup.enter()
queue.async(group: batchGroup) {

if updateArray.count > 0
{
updateCompanies = [Company]()


for (index,item) in updateArray.enumerated()
{
let company = self.returnComapnyOjectfromDictionary(item as NSDictionary)
updateCompanies!.append(company)
print("update loop----\(index)")

}
}
batchGroup.leave()
}

batchGroup.enter()
queue.async(group: batchGroup) {

for (_,item) in deleteArray.enumerated()
{

let company = self.returnComapnyOjectfromDictionary(item as NSDictionary)
_ = self.removeObject(&self.companies!,object: company)
print("looop2")

}

batchGroup.leave()
}


batchGroup.notify(queue: .global(qos: .background))
{

if updateCompanies?.count == updateArray.count{

//self.companies = Array(comapnySet)
print("count before \(self.companies?.count)")

comapnySet.subtract(Set(updateCompanies!))
self.companies = Array(comapnySet)

// self.companies = Array(comapnySet.intersection(Set(updateCompanies!)))
print("after delete \(self.companies?.count)")

self.companies!.append(contentsOf: updateCompanies!)


print("update array count \(updateArray.count) ----- and update Companies count --\(self.companies?.count)")
updateCompanies = nil

}
if addCompanies?.count == addArray.count
{
self.companies!.append(contentsOf: addCompanies!)
print("add array count \(addArray.count) ----- and add Companies count --\(addCompanies?.count)")

addCompanies = nil
}

}

batchGroup.wait()
}
}

//**Below code is executed before queue completion**
if let status = json["STATUS"] as? String
{
dataDict[self.constants!.defaultsKeys.RESPONSE_STATUS] = status
}
if let message = json["MESSAGE"] as? String
{
dataDict[self.constants!.defaultsKeys.RESPONSE_MESSAGE] = message
}
}

var newCompanyArray:Array<AnyObject> = []
var dict = Dictionary<String,String>()


for cmp in self.companies!
{
dict["ORG_CODE"] = cmp.orgCode
dict["ORG_DESCRIPTION"] = cmp.orgDescription
dict["OBX_BTL_CODE"] = cmp.orgBtlCode
dict["BTL_DESCRIPTION"] = cmp.orgBtlDescription
dict["ORG_STATUS"] = cmp.orgStatus

newCompanyArray.append(dict as AnyObject)
}

let isValidJson = JSONSerialization.isValidJSONObject(newCompanyArray)


if newCompanyArray.count > 0 && isValidJson
{
let companyCount = newCompanyArray.count - oldCompanies.count

let replaceComCount = self.utility!.replace(self.constants!.logs.LOG_COMPANY_SYNC_END,originalString: "<COUNT>",withString: "\(companyCount)")


self.parser!.setLogValueToXml(replaceComCount, logType:
self.constants!.logs.LOG_TYPE_ACTIVITY, fileLogType: "")


let dataFinal:Data = try! JSONSerialization.data(withJSONObject: newCompanyArray, options: [])
self.fileMgr.removeFile(self.fileMgr.getDocumentFilePath(self.fileMgr.getCacheData(self.constants!.COMPANIES_LAST_SYNCH_DATE) as! String))
let compniesFileName = "Companies_\(self.dateUtil.getCurrentDateTime())" //logic is to be use in synch
self.fileMgr.setCacheData(compniesFileName as AnyObject, key: self.constants!.COMPANIES_LAST_SYNCH_DATE)

self.fileMgr.writeFile(NSString(data: dataFinal, encoding: String.Encoding.utf8.rawValue)!,fileName :self.fileMgr.getCacheData(self.constants!.COMPANIES_LAST_SYNCH_DATE) as! String,documentDir:self.fileMgr.getDocumentPath())

}

}

completionHandler(companyFile)
}
DispatchQueue.global(qos: .background).async
{
self.loadCompaniesFromSynch(jNsData, completionHandler:
{
companyFile in

if !companyFile.isEmpty
{
self.doPropertySync()
}
else
{

}
})
}

最佳答案

你混淆了很多东西。您在尝试接收通知,但也在尝试等待。

您的 completion() 处理程序和标有

的代码

//Below code is executed before queue completion"

在您的通知 block 之外调用/运行...

AFAICS,没有理由在 loadCompaniesFromSynch() 中使用 notifywait,因为您不调用任何异步任务

据我了解,您想做的是在后台执行繁重的 io 操作。在这种情况下,删除所有 DispatchGroup 内容并调度 hole 函数。无需等待/通知,因为您正在使用完成处理程序。检查以下内容以了解想法:

    func loadCompaniesFromSynch(_ data: Data, completionHandler: @escaping(String) -> ()) {
// dispatch the whole thing to the global background queue
DispatchQueue.global(qos: .background).async {

// your original code with all DispatchGroup stuff deleted

// call completion handler on main queue, so the caller does not have to care
DispatchQueue.main.async {
completionHandler(companyFile)
}
}
}

self.loadCompaniesFromSynch(jNsData) {
companyFile in

// do stuff after loadCompaniesFromSynch finished
}

希望这对您有所帮助。

关于ios - 完成处理程序无法按预期与 Dispatch Group 和 Concurrent Queue 一起工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41184178/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com