我从Json检索了值,每次都打印检索到的值更改顺序(位置已更改)。请检查我的下面代码一次:
override func viewDidLoad() {
super.viewDidLoad()
var myIds = [104016, 104010, 104014, 104018, 104000, 104038, 104015, 104011, 104015, 104010, 104010, 104010, 104003, 104003, 104011]
for arr in 0 ..< myIds.count-1 {
let url = URL(string: "http://.........\(myIds[arr])")
print("myIds[\(arr)]:\(myIds[arr])")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil
{
print ("ERROR")
}
else
{
if let content = data
{
do
{
//Array
let myJson = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
var i = myJson["Job_title_name"]!
var ist = ""
// print("i=\(i)")
ist = String(describing: i!)
print("myIds[\(arr)]=\(ist)")
}
catch
{
}
}
}
}
task.resume()
}
}
**output:**
myIds[0]:104016
myIds[1]:104010
myIds[2]:104014
myIds[3]:104018
myIds[4]:104000
myIds[5]:104038
myIds[6]:104015
myIds[7]:104011
myIds[8]:104015
myIds[9]:104010
myIds[10]:104010
myIds[11]:104010
myIds[12]:104003
myIds[13]:104003
myIds[0]=WebLogic Admin
myIds[3]=OracleDevloper
myIds[2]=Node Js Developer
myIds[1]=Angular Developer
myIds[6]=HTML&CSS Developer
myIds[5]=Senior Manager
myIds[7]=CRM Developer
myIds[4]=Windows Manager
myIds[8]=HTML&CSS Developer
myIds[9]=Angular Developer
myIds[11]=Angular Developer
myIds[10]=Angular Developer
myIds[12]=java developer
myIds[13]=java developer
每次停止并运行应用程序时,此输出都会更改。但我无法找到问题。请检查我的代码一次。
必填项:
myIds[0]:104016
myIds[1]:104010
myIds[2]:104014
myIds[3]:104018
myIds[4]:104000
myIds[5]:104038
myIds[6]:104015
myIds[7]:104011
myIds[8]:104015
myIds[9]:104010
myIds[10]:104010
myIds[11]:104010
myIds[12]:104003
myIds[13]:104003
myIds[0]=WebLogic Admin
myIds[1]=Angular Developer
myIds[2]=Node Js Developer
myIds[3]=OracleDevloper
myIds[4]=Windows Manager
myIds[5]=Senior Manager
myIds[6]=HTML&CSS Developer
myIds[7]=CRM Developer
myIds[8]=HTML&CSS Developer
myIds[9]=Angular Developer
myIds[10]=Angular Developer
myIds[11]=Angular Developer
myIds[12]=java developer
myIds[13]=java developer
我想要上面的输出。在上面的代码中是我的错误。
答案 0 :(得分:1)
网络请求以异步方式运行,因此这是预期的行为。请求不会按照与启动时相同的顺序完成。
如果您需要按顺序运行请求,则可以使用DispatchGroups
运行它们,但这会导致性能降低,因为您的异步请求是按顺序而不是并行执行的。更好的解决方案是将结果存储在数据结构中,您可以根据索引之外的唯一标识符来识别对象。对于您当前的问题,最佳解决方案是将结果存储在字典中,其中键是id,值是网络请求中的值。
使用Dictionary存储输出值的并发解决方案:
override func viewDidLoad() {
super.viewDidLoad()
var myIds = [104016, 104010, 104014, 104018, 104000, 104038, 104015, 104011, 104015, 104010, 104010, 104010, 104003, 104003, 104011]
var jobTitles = [Int:String]()
let group = DispatchGroup()
for arr in 0 ..< myIds.count-1 {
let url = URL(string: "http://.........\(myIds[arr])")
print("myIds[\(arr)]:\(myIds[arr])")
group.enter()
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil{
print ("ERROR")
} else {
if let content = data{
do {
guard let myJson = try JSONSerialization.jsonObject(with: content, options: []) as? [String:Any] else {return}
guard let jobTitle = myJson["Job_title_name"] as? String else {return}
jobTitles[myIds[arr]] = jobTitle
group.leave()
} catch {
}
}
}
}
task.resume()
}
}
}
group.notify(queue: DispatchQueue.main, execute: {
print(jobTitles)
})
一些一般性建议:不要强制从服务器响应中解包值,也不要使用String(describing:)
来创建字符串。使用可选的绑定或默认值来安全地解包选项,如果它们是字符串值,则将值转换为String;或者只使用String(value)
表示可以直接初始化字符串的值(例如Int
)。
答案 1 :(得分:1)
URLSession.shared.dataTask()通常在并行执行中调用API,因此无论调用请求顺序是否与响应顺序相同。
如果您想以相同的顺序调用请求并获得响应,那么您应该创建NSOperation队列并依赖它。