iOS swift 如何在需要 return 值的函数内等待异步任务
iOS swift how can I await an async task inside a function that needs a return value
我正在使用 swift 3.0 并创建了一个 return 是整数数组的函数。整数数组非常具体,它们是从数据库中获取的,因此 HTTP 调用是异步的。这是一个函数,因为我在 3 个不同的控制器中使用它,所以写一次是有意义的。我的问题是异步代码是 returned 在底部的 return 语句之后,因此它是 returning nil 。我在这里 尝试了示例,但是它不起作用,主要是因为我需要 return 值。这是我的代码
func ColorSwitch(label: [UILabel]) -> [Int] {
for (index, _) in label.enumerated() {
label[index].isHidden = true
}
// I need the value of this variable in the return
// statement after the async is done
var placeArea_id = [Int]()
let urll:URL = URL(string:ConnectionString+"url")!
let sessionn = URLSession.shared
var requestt = URLRequest(url: urll)
requestt.httpMethod = "POST"
let group = DispatchGroup()
group.enter()
let parameterr = "http parameters"
requestt.httpBody = parameterr.data(using: String.Encoding.utf8)
let task = sessionn.dataTask(with:requestt, completionHandler: {(data, response, error) in
if error != nil {
print("check check error")
} else {
do {
let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String:Any]
DispatchQueue.main.async {
if let Profiles = parsedData?["Results"] as? [AnyObject] {
if placeArea_id.count >= 0 {
placeArea_id = [Int]()
}
for Profiles in Profiles {
if let pictureS = Profiles["id"] as? Int {
placeArea_id.append(pictureS)
}
}
}
group.leave()
}
} catch let error as NSError {
print(error)
}
}
})
task.resume()
group.notify(queue: .main) {
// This is getting the value however can't return it here since it
// expects type Void
print(placeArea_id)
}
// this is nil
return placeArea_id
}
我已经检查过,值在异步代码中 returning 现在只需要 return 任何建议都很好。
为此您需要使用闭包,或者将您的函数更改为同步。
func ColorSwitch(label: [UILabel], completion:@escaping ([Int])->Void) {
completion([1,2,3,4]) // when you want to return
}
ColorSwitch(label: [UILabel()]) { (output) in
// output is the array of ints
print("output: \(output)")
}
这是一篇关于闭包的非常好的博客http://goshdarnclosuresyntax.com/
您的函数 return 不能真正从该函数中的异步操作中获取值。这将破坏异步性的目的。为了将该数据传回 ColorSwitch(label:)
函数之外,您还需要让它接受一个将在完成时调用的闭包,该闭包接受 [Int]
作为参数。您的方法声明需要如下所示:
func ColorSwitch(label: [UILabel], completion: @escaping ([Int]) -> Void) -> Void {
for (index, _) in label.enumerated() {
label[index].isHidden = true
}
var placeArea_id = [Int]()
let urll:URL = URL(string:ConnectionString+"url")!
let sessionn = URLSession.shared
var requestt = URLRequest(url: urll)
requestt.httpMethod = "POST"
let group = DispatchGroup()
group.enter()
let parameterr = "http parameters"
requestt.httpBody = parameterr.data(using: String.Encoding.utf8)
let task = sessionn.dataTask(with:requestt, completionHandler: {(data, response, error) in
if error != nil {
print("check check error")
} else {
do {
let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String:Any]
DispatchQueue.main.async {
if let Profiles = parsedData?["Results"] as? [AnyObject] {
if placeArea_id.count >= 0 {
placeArea_id = [Int]()
}
for Profiles in Profiles {
if let pictureS = Profiles["id"] as? Int {
placeArea_id.append(pictureS)
}
}
}
group.leave()
completion(placeArea_id) // This is effectively your "return"
}
} catch let error as NSError {
print(error)
}
}
})
task.resume()
}
以后可以这样称呼:
ColorSwitch(label: []) { (ids: [Int]) in
print(ids)
}
我正在使用 swift 3.0 并创建了一个 return 是整数数组的函数。整数数组非常具体,它们是从数据库中获取的,因此 HTTP 调用是异步的。这是一个函数,因为我在 3 个不同的控制器中使用它,所以写一次是有意义的。我的问题是异步代码是 returned 在底部的 return 语句之后,因此它是 returning nil 。我在这里
func ColorSwitch(label: [UILabel]) -> [Int] {
for (index, _) in label.enumerated() {
label[index].isHidden = true
}
// I need the value of this variable in the return
// statement after the async is done
var placeArea_id = [Int]()
let urll:URL = URL(string:ConnectionString+"url")!
let sessionn = URLSession.shared
var requestt = URLRequest(url: urll)
requestt.httpMethod = "POST"
let group = DispatchGroup()
group.enter()
let parameterr = "http parameters"
requestt.httpBody = parameterr.data(using: String.Encoding.utf8)
let task = sessionn.dataTask(with:requestt, completionHandler: {(data, response, error) in
if error != nil {
print("check check error")
} else {
do {
let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String:Any]
DispatchQueue.main.async {
if let Profiles = parsedData?["Results"] as? [AnyObject] {
if placeArea_id.count >= 0 {
placeArea_id = [Int]()
}
for Profiles in Profiles {
if let pictureS = Profiles["id"] as? Int {
placeArea_id.append(pictureS)
}
}
}
group.leave()
}
} catch let error as NSError {
print(error)
}
}
})
task.resume()
group.notify(queue: .main) {
// This is getting the value however can't return it here since it
// expects type Void
print(placeArea_id)
}
// this is nil
return placeArea_id
}
我已经检查过,值在异步代码中 returning 现在只需要 return 任何建议都很好。
为此您需要使用闭包,或者将您的函数更改为同步。
func ColorSwitch(label: [UILabel], completion:@escaping ([Int])->Void) {
completion([1,2,3,4]) // when you want to return
}
ColorSwitch(label: [UILabel()]) { (output) in
// output is the array of ints
print("output: \(output)")
}
这是一篇关于闭包的非常好的博客http://goshdarnclosuresyntax.com/
您的函数 return 不能真正从该函数中的异步操作中获取值。这将破坏异步性的目的。为了将该数据传回 ColorSwitch(label:)
函数之外,您还需要让它接受一个将在完成时调用的闭包,该闭包接受 [Int]
作为参数。您的方法声明需要如下所示:
func ColorSwitch(label: [UILabel], completion: @escaping ([Int]) -> Void) -> Void {
for (index, _) in label.enumerated() {
label[index].isHidden = true
}
var placeArea_id = [Int]()
let urll:URL = URL(string:ConnectionString+"url")!
let sessionn = URLSession.shared
var requestt = URLRequest(url: urll)
requestt.httpMethod = "POST"
let group = DispatchGroup()
group.enter()
let parameterr = "http parameters"
requestt.httpBody = parameterr.data(using: String.Encoding.utf8)
let task = sessionn.dataTask(with:requestt, completionHandler: {(data, response, error) in
if error != nil {
print("check check error")
} else {
do {
let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String:Any]
DispatchQueue.main.async {
if let Profiles = parsedData?["Results"] as? [AnyObject] {
if placeArea_id.count >= 0 {
placeArea_id = [Int]()
}
for Profiles in Profiles {
if let pictureS = Profiles["id"] as? Int {
placeArea_id.append(pictureS)
}
}
}
group.leave()
completion(placeArea_id) // This is effectively your "return"
}
} catch let error as NSError {
print(error)
}
}
})
task.resume()
}
以后可以这样称呼:
ColorSwitch(label: []) { (ids: [Int]) in
print(ids)
}