从另一个 class 访问 DispatchGroup

Access DispatchGroup from another class

是否可以从另一个 class 访问 DispatchGroup? 假设我在 class Loginfunctions.swift 中有以下函数(在 func 中定义了 var loginQueue = DispatchGroup.init()):

func logUserIn(emaila: String!, passworda: String!, urlPath: String!, completionHandler:@escaping (NSDictionary) -> Void)  {
     DispatchQueue.global(qos: .userInitiated).async {

     let requestURL = NSURL(string: urlPath)!
     let request = NSMutableURLRequest(url: requestURL as URL)
     request.httpMethod = "POST"
     let emailtext = emaila
     let passwordtext = passworda

     let postParameters = "email="+emailtext!+"&password="+passwordtext!;
     request.httpBody = postParameters.data(using: .utf8)

     DispatchGroup.enter(loginQueue)()

     //creating a task to send the post request
     let task = URLSession.shared.dataTask(with: request as URLRequest) {
         data, response, error in

         if error != nil{
             print("error is \(error)")
             return;
         }

         do {
             //converting resonse to NSDictionary
             let myJSON =  try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary
             DispatchGroup.wait(self.loginQueue)()
                 DispatchQueue.main.async {
                     completionHandler(myJSON)
                 }
         } catch {
             print(error)
         }
     }

     //executing the task
     task.resume()
     DispatchGroup.leave(self.loginQueue)()
    }
 }

从另一个 Class (LoginViewController.swift) 调用以下内容会导致 TEMP_VAR_FOR_LOGIN 的不同值(LoginViewController.swift 中的实例):

@IBAction func userLogin(_ sender: UIButton) {
            self.loginFunctions.logUserIn(emaila: self.email.text, passworda: self.password.text, urlPath: "URL_PATH_WAS_ENTERED_HERE")   {
                (completionHandler) in
                self.TEMP_VAR_FOR_LOGIN = completionHandler
                print("*****************")
                print(self.TEMP_VAR_FOR_LOGIN)
            }

            print("################")
            print(TEMP_VAR_FOR_LOGIN)
}

控制台输出为

Some other stuff...
#################
{
}
More other stuff...
*****************
{
The Data I need : Out of the Closure
}

对问题所在有帮助吗?

P.S。菜鸟在这里 ;)

URLSessionTask 方法本身是一个异步任务。所以,这里没有必要使用DispatchGrouplogUserIn函数可以修改如下:

func logUserIn(emaila: String!, passworda: String!, urlPath: String!, completionHandler:@escaping (NSDictionary) -> Void)  {

    let emailtext = emaila
    let passwordtext = passworda

    let postParameters = "email="+emailtext!+"&password="+passwordtext!;

    let requestURL = URL(string: urlPath)!
    var request = URLRequest(url: requestURL)
    request.httpMethod = "POST"
    request.httpBody = postParameters.data(using: .utf8)

    //creating a task to send the post request
    let session = URLSession(configuration: URLSessionConfiguration.default)
    let task: URLSessionDataTask = session.dataTask(with: request, completionHandler: { data, response, error in

        if error != nil {
            print(error)
        }else {
            do {
                //converting resonse to NSDictionary
                let myJSON =  try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary
                DispatchQueue.main.async {
                    completionHandler(myJSON)
                }
            } catch {
                print(error)
            }
        }
    })

    task.resume()
}

其次,您在这里使用closure的方式是错误的。它的用法如下:

var dictionaryObj:NSMutableDictionary = NSMutableDictionary() //global - defined outside functions

self.logUserIn(emaila: "lal", passworda: "lal", urlPath: "lal", completionHandler: { dictionaryObj in
    self.dictionaryObj = dictionaryObj as! NSMutableDictionary
    print(dictionaryObj)
    print(self.dictionaryObj)
})