异步调用之后的延迟函数仍然在异步调用之前被调用

时间:2016-11-08 16:23:02

标签: ios swift asynchronous core-data alamofire

所以我有3个功能需要执行以下操作:

  1. fetchNewMetaData()使用Alamofire&amp ;;从网络服务器获取数据使用SyncDB将JSON响应与核心数据实体同步。
  2. fetchCurrentMetaObjects()从Core Data Entity中获取对象,并将这些对象附加到[NSManagedObject]数组中。
  3. applyLabels(label:UILabel, metaKey:String)根据提供的metaKey将[NSManagedObject]数组的值应用于指定的标签。
  4. 以下是功能代码:

    var items = [NSManagedObject]()
    
    func fetchNewMetaData() {
        let parameters: Parameters = ["email": email!, "password": password!]
        let headers: HTTPHeaders = ["Content-Type": "application/x-www-form-urlencoded"]
        Alamofire.request("https://mywebsite.com/Sync.php", method: .post, parameters: parameters, headers: headers).validate().responseJSON { response in            
            if let jsonResult = response.result.value {
                let json = JSON(jsonResult)
                let jsonData = json["data"]
                print("JSON DATA : \(jsonData)")
                let jsonString = jsonData.description
                let stringData = jsonString.data(using: String.Encoding.utf8)
                let serializedJSON = try! JSONSerialization.jsonObject(with: stringData!, options: []) as! [[String : Any]]
    
                Sync.changes(serializedJSON, inEntityNamed: "Usermeta", dataStack: self.dataStack) { error in
                    self.fetchCurrentMetaObjects()
                }
            }
        }
    }
    
    func fetchCurrentMetaObjects() {
        let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Usermeta")
        request.sortDescriptors = [NSSortDescriptor(key: "remoteID", ascending: true)]
        self.items = (try! dataStack.mainContext.fetch(request)) as! [NSManagedObject]
    }
    
    func applyLabels(label:UILabel, metaKey:String) {
        for item in items as! [NSManagedObject] {
            if let savedMetaKey = item.value(forKey: metaKey) as? String {
                label.text = savedMetaKey
            }
        }
    }
    

    但是当我使用以下代码调用这些函数时,标签不会改变:

    override func viewDidLoad() {
        super.viewDidLoad()
    
        self.fetchNewMetaData()
        self.fetchCurrentMetaObjects()
        DispatchQueue.main.async {
            self.applyLabels(label: self.label, metaKey: "firstName")
        }
    }
    

    我发现有几个线程在讨论SO上的调度组和队列但是所有这些线程都是基于Swift 2或Obj-C语法而没有应用于Swift 3.请问有什么问题在这里?我知道数据已保存到CoreData但看起来applyLabels()fetchcNewMetaData()fetchCurrentMetaObjects()之前被调用了。

    谢谢!

1 个答案:

答案 0 :(得分:0)

fetchNewMetaData方法将在您收到alamofire响应之前返回。如果你在该方法中设置断点,你会注意到它在方法结束之前击中了最后一个},然后它进入Alamofire响应,然后它会返回并在片刻后点击Alamofire响应。

我假设您要按以下顺序调用方法? fetchNewMetaData - &gt;一旦得到回复 - &gt; fetchCurrentMetaObjects - &gt;完成后 - &gt;申请标签

如果是这种情况,请在Sync.change之后调用alamofire调用中的fetchCurrentMetaObjects,这意味着在获得响应之前不会调用fetchCurrentMetaObjects。

然后,在DispatchQueue.main.async中的fetchCurrentMetaObjects末尾调用applyLabels。

在你的viewDidLoad中,你应该调用的是fetchNewMetaData,然后它应该按顺序排列。让我知道这对你有用。