iOS/Swift中的同步代码
我是iOS编程新手。我正在尝试使函数中的一段代码同步,但它似乎不起作用:iOS/Swift中的同步代码,ios,swift,synchronization,Ios,Swift,Synchronization,我是iOS编程新手。我正在尝试使函数中的一段代码同步,但它似乎不起作用: func fetchLocationsList(searchText:String)->Array<String> { print ("searched text:\(searchText)") let url = URL(string:"http://api.openweathermap.org/data/2.5/find?q=\(searchText)&ty
func fetchLocationsList(searchText:String)->Array<String> {
print ("searched text:\(searchText)")
let url = URL(string:"http://api.openweathermap.org/data/2.5/find?q=\(searchText)&type=like&sort=name&cnt=9&APPID=a33aa72")
//Using Alamofire to handle http requests
Alamofire.request(url!).responseJSON {response in
guard let jsonResponse = response.result.value as? [String:Any]
else { print ("error in json response")
return}
guard let list = jsonResponse["list"] as? NSArray else {return}
let lockQueue = DispatchQueue(label:"Et.My-Weather-App.queue1")
_ = lockQueue.sync{
for index in 0..<list.count {
print ("index is: \(index)")
guard let listElement = list[index] as? [String:Any] else {return}
let id = listElement["id"] as! Int
print ("id is: \(id)")
let cityName = listElement["name"] as! String
print ("cityName is: \(cityName)")
let sys = listElement["sys"] as! [String:Any]
let country = sys["country"] as! String
print ("country is: \(country)")
let element = "\(cityName), \(country), \(id)"
print ("\(element)")
self.resultsArray.append(element)
}
}
}
if self.resultsArray.count==0 {
print ("results array is also zero!")
}
return self.resultsArray
}
func fetchLocationsList(searchText:String)->Array{
打印(“搜索文本:\(搜索文本)”)
让url=url(字符串:http://api.openweathermap.org/data/2.5/find?q=\(searchText)&type=like&sort=name&cnt=9&APPID=a33aa72”)
//使用Alamofire处理http请求
Alamofire.request(url!).responseJSON{中的响应
guard let jsonResponse=response.result.value为?[String:Any]
else{print(“json响应中的错误”)
返回}
guard let list=jsonResponse[“list”]作为?NSArray else{return}
让lockQueue=DispatchQueue(标签:“Et.My-Weather-App.queue1”)
_=lockQueue.sync{
对于0..中的索引,我建议您这样做,因为异步任务很麻烦,而且效果很好
func fetchLocationsList(searchText:String, completion: @escaping (_ results:Array<String>)->()){
print ("searched text:\(searchText)")
let url = URL(string:"http://api.openweathermap.org/data/2.5/find?q=\(searchText)&type=like&sort=name&cnt=9&APPID=a33aa72")
//Using Alamofire to handle http requests
Alamofire.request(url!).responseJSON {response in
guard let jsonResponse = response.result.value as? [String:Any] else { print ("error in json response"); return}
guard let list = jsonResponse["list"] as? Array<Dictionary<String,Any>> else { return }
var array = Array<String>() // create an array to store results.
for item in list {
let id = item["id"] as! Int
let cityName = item["name"] as! String
let sys = item["sys"] as! Dictionary<String,Any>
let country = sys["country"] as! String
let element = "\(cityName), \(country), \(id)"
array.append(element) // add to that array.
}
completion(array) //send the array via the completions handler.
}
}
您不能从异步进程返回值,例如从网络中检索内容。相反,请将闭包传递给fetchLocationsList
函数,并从网络完成闭包中调用该函数。在iOS中,理解异步进程并为其编码非常重要;不要简单地尝试和使用闭包e呼叫同步。这将使你的应用程序无响应。@Paulw11,我的问题看起来可能重复,但我不会考虑寻找“如何从Alamofire返回值”这样的问题。我的问题是关于同步代码的,不是关于Alamofire。好的,但是您接受的答案毫无意义地将for
循环分派到另一个队列;真正的解决方法是完成(数组)
现在位于AlamoFire闭包内,这是我提到的解决方案,也是副本中的解决方案。fetchLocationList
仍然不是一个同步函数;请注意,它没有返回语句。如果您确实希望在网络操作完成之前阻止fetchLocationList
,则解决方案是使用DispatchGroup
,但是同步功能是一个糟糕的主意,而且询问重复的问题也不会让人感觉不舒服;虽然如果您可以搜索并找到您要查找的内容是很好的,但在本例中您没有。现在您的问题被添加到集合中,如果其他人搜索,他们可能会找到您的问题;重复链接可以帮助他们找到正确的答案,你是对的,我删除了我代码中的另一个队列。我是一个初学者,除了坏主意之外什么都没有。:)太完美了。lockQueue.sync
完全没有必要。瞧@Paulw11我只是添加了代码来解决他的问题。检查他的其他代码是否正确不是原始问题的一部分。所以你的前面的评论完全没有必要。而且,如果你是否决我答案的人,你应该在回答问题时重新考虑,他的原始代码的其他部分可能不正确这一事实不应该反映在我的答案上。@benny,那很好。很高兴我能帮上忙。如果出现错误,你不会打电话给完成处理程序r、 坏事会发生:)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
fetchLocationsList(searchText: "Whatever this string is") { (results) in
self.resultsArray.append(contentsOf: results)
// Then do anything else you need to do after this function has completed within this closure.
}
}