Swift dispatch_async 来自函数
Swift dispatch_async from function
我如何才能等到函数从 alamofire 获取请求获取所有数据?
GetData.swift 文件:
import Foundation
import Alamofire
import SwiftyJSON
import ObjectMapper
func getStartData() -> Void {
let sharedBranch = BranchSingleton.sharedInstance
let sharedArticle = ArticleSingleton.sharedInstance
Alamofire.request(.GET, Config().apiBranch)
.responseJSON { request, response, result in
let jsonObj = SwiftyJSON.JSON(result.value!)
for obj in jsonObj {
let branch = Mapper<Branch>().map(obj.1.rawString()!)
sharedBranch.addBranch(branch!)
}
}
Alamofire.request(.GET, Config().apiArticle)
.responseJSON { request, response, result in
let jsonObj = SwiftyJSON.JSON(result.value!)
for obj in jsonObj {
let article = Mapper<Article>().map(obj.1.rawString()!)
sharedArticle.addArticle(article!)
}
}
}
ViewController.swift 文件:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
getStartData() // need to wait until all requests are finished then do print
print(sharedArticle.articleList)
}
}
SingletonObj.swift 文件:
import Foundation
class BranchSingleton {
var branchList: [Branch] = []
class var sharedInstance: BranchSingleton {
struct Static {
static let instance: BranchSingleton = BranchSingleton()
}
return Static.instance
}
func addBranch(branch: Branch) {
branchList.append(branch)
}
}
class ArticleSingleton {
var articleList: [Article] = []
class var sharedInstance: ArticleSingleton {
struct Static {
static let instance: ArticleSingleton = ArticleSingleton()
}
return Static.instance
}
func addArticle(article: Article) {
articleList.append(article)
}
}
我需要等到 getStartData()
完成,然后弹出单例数组..
我该怎么做?
这个 getStartData 包含超过 2 个请求,但我只是举了 2 个的例子..
你问的不是问题。 没有理由到"wait"。你也不能。你只是做你做的,异步的。同时界面必须保持活动状态;用户必须能够继续工作。因此 "wait" for.
没有任何意义
现在,如果问题是,当所有请求都完成后,如何以某种优雅的方式向应用程序的其余部分发送信号,一个好的答案是使用 NSProgress。所有不同的请求都可以促成一个共同的 NSProgress 对象。好处是它的 fractionCompleted
可以通过 KVO 观察到,所以当它大于或等于 1.0
时,你就完成了。
但你实际上并不需要 NSProgress;你可以只增加或减少一个 KVO 可观察的实例变量(当然要小心线程)。如果您知道有 n
个进程,那么您可以在 n
处启动一个变量,并让每个进程在完成时递减它; didSet
变量的观察者可以在我们达到零时采取行动。
关键是:你不需要 "wait":你只是让所有不同的活动都对一些共同的中心价值做出贡献,"knows" 这意味着我们已经 "finished" 并且然后可以采取行动。
正如@Matt 所说,您不能也不应该尝试等到 Alamofire 完成您的请求。这就像雇人 运行 跑腿,这样你就可以工作,然后停止一切,坐在门口,直到他们回来。您还不如自己 运行 去办事。
抛开类比,您还不如同步执行任务。然而,同步网络是一个非常糟糕的主意。它会冻结 UI 直到网络请求完成,如果出现问题,这可能会等待很长时间。
像 Alamofire 的请求方法这样的异步方法需要一个完成块,工作完成时应该是 运行 的代码块。
请求方法 returns 立即,甚至在请求发送到服务器之前,更不用说完成了。
与其等待请求完成,不如重构 getStartData 方法以获取完成处理程序,并在工作完成后使用 that 进行响应:
func getStartData(completion: () -> void) -> Void {
let sharedBranch = BranchSingleton.sharedInstance
let sharedArticle = ArticleSingleton.sharedInstance
Alamofire.request(.GET, Config().apiBranch)
.responseJSON { request, response, result in
let jsonObj = SwiftyJSON.JSON(result.value!)
for obj in jsonObj {
let branch = Mapper<Branch>().map(obj.1.rawString()!)
sharedBranch.addBranch(branch!)
}
}
Alamofire.request(.GET, Config().apiArticle)
.responseJSON { request, response, result in
let jsonObj = SwiftyJSON.JSON(result.value!)
for obj in jsonObj {
let article = Mapper<Article>().map(obj.1.rawString()!)
sharedArticle.addArticle(article!)
}
//At this point the Alamofire .GET request for Config().apiArticle
//is complete. Call our completion block (passed in as a parameter)
completion()
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
getStartData()
{
//This is a "trailing closure", a block of code passed to getStartData
print("At this point, we've finished getting our data from Alamofire.")
print(sharedArticle.articleList)
}
}
}
请注意,您的 getStartData
方法连续执行 2 个 Alamofire.request()
命令。如果第二个请求要求第一个请求完成,那么您将需要重组该代码,以便第二个 Alamofire 请求位于第一个调用的完成块内。 (这比我现在心情要做的编辑要多。)
我如何才能等到函数从 alamofire 获取请求获取所有数据?
GetData.swift 文件:
import Foundation
import Alamofire
import SwiftyJSON
import ObjectMapper
func getStartData() -> Void {
let sharedBranch = BranchSingleton.sharedInstance
let sharedArticle = ArticleSingleton.sharedInstance
Alamofire.request(.GET, Config().apiBranch)
.responseJSON { request, response, result in
let jsonObj = SwiftyJSON.JSON(result.value!)
for obj in jsonObj {
let branch = Mapper<Branch>().map(obj.1.rawString()!)
sharedBranch.addBranch(branch!)
}
}
Alamofire.request(.GET, Config().apiArticle)
.responseJSON { request, response, result in
let jsonObj = SwiftyJSON.JSON(result.value!)
for obj in jsonObj {
let article = Mapper<Article>().map(obj.1.rawString()!)
sharedArticle.addArticle(article!)
}
}
}
ViewController.swift 文件:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
getStartData() // need to wait until all requests are finished then do print
print(sharedArticle.articleList)
}
}
SingletonObj.swift 文件:
import Foundation
class BranchSingleton {
var branchList: [Branch] = []
class var sharedInstance: BranchSingleton {
struct Static {
static let instance: BranchSingleton = BranchSingleton()
}
return Static.instance
}
func addBranch(branch: Branch) {
branchList.append(branch)
}
}
class ArticleSingleton {
var articleList: [Article] = []
class var sharedInstance: ArticleSingleton {
struct Static {
static let instance: ArticleSingleton = ArticleSingleton()
}
return Static.instance
}
func addArticle(article: Article) {
articleList.append(article)
}
}
我需要等到 getStartData()
完成,然后弹出单例数组..
我该怎么做?
这个 getStartData 包含超过 2 个请求,但我只是举了 2 个的例子..
你问的不是问题。 没有理由到"wait"。你也不能。你只是做你做的,异步的。同时界面必须保持活动状态;用户必须能够继续工作。因此 "wait" for.
没有任何意义现在,如果问题是,当所有请求都完成后,如何以某种优雅的方式向应用程序的其余部分发送信号,一个好的答案是使用 NSProgress。所有不同的请求都可以促成一个共同的 NSProgress 对象。好处是它的 fractionCompleted
可以通过 KVO 观察到,所以当它大于或等于 1.0
时,你就完成了。
但你实际上并不需要 NSProgress;你可以只增加或减少一个 KVO 可观察的实例变量(当然要小心线程)。如果您知道有 n
个进程,那么您可以在 n
处启动一个变量,并让每个进程在完成时递减它; didSet
变量的观察者可以在我们达到零时采取行动。
关键是:你不需要 "wait":你只是让所有不同的活动都对一些共同的中心价值做出贡献,"knows" 这意味着我们已经 "finished" 并且然后可以采取行动。
正如@Matt 所说,您不能也不应该尝试等到 Alamofire 完成您的请求。这就像雇人 运行 跑腿,这样你就可以工作,然后停止一切,坐在门口,直到他们回来。您还不如自己 运行 去办事。
抛开类比,您还不如同步执行任务。然而,同步网络是一个非常糟糕的主意。它会冻结 UI 直到网络请求完成,如果出现问题,这可能会等待很长时间。
像 Alamofire 的请求方法这样的异步方法需要一个完成块,工作完成时应该是 运行 的代码块。
请求方法 returns 立即,甚至在请求发送到服务器之前,更不用说完成了。
与其等待请求完成,不如重构 getStartData 方法以获取完成处理程序,并在工作完成后使用 that 进行响应:
func getStartData(completion: () -> void) -> Void {
let sharedBranch = BranchSingleton.sharedInstance
let sharedArticle = ArticleSingleton.sharedInstance
Alamofire.request(.GET, Config().apiBranch)
.responseJSON { request, response, result in
let jsonObj = SwiftyJSON.JSON(result.value!)
for obj in jsonObj {
let branch = Mapper<Branch>().map(obj.1.rawString()!)
sharedBranch.addBranch(branch!)
}
}
Alamofire.request(.GET, Config().apiArticle)
.responseJSON { request, response, result in
let jsonObj = SwiftyJSON.JSON(result.value!)
for obj in jsonObj {
let article = Mapper<Article>().map(obj.1.rawString()!)
sharedArticle.addArticle(article!)
}
//At this point the Alamofire .GET request for Config().apiArticle
//is complete. Call our completion block (passed in as a parameter)
completion()
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
getStartData()
{
//This is a "trailing closure", a block of code passed to getStartData
print("At this point, we've finished getting our data from Alamofire.")
print(sharedArticle.articleList)
}
}
}
请注意,您的 getStartData
方法连续执行 2 个 Alamofire.request()
命令。如果第二个请求要求第一个请求完成,那么您将需要重组该代码,以便第二个 Alamofire 请求位于第一个调用的完成块内。 (这比我现在心情要做的编辑要多。)