Swift 闭包返回值(以前的completionBlock)

Swift 闭包返回值(以前的completionBlock),swift,ios8,Swift,Ios8,我想在长期操作完成后返回一些值。 但是,此外,我想将逻辑和gui分开 比如,;我有两节课 SomeServices.swift,其方法名为“getDataFromService…” MyTableViewController.swift将显示“getDataFromService”的结果 因此,在前面的Objective-C中,我刚刚在一些服务中添加了一个方法,如下所示: (void)getDataFromService:(void (^)(NSArray *, NSError *))compl

我想在长期操作完成后返回一些值。 但是,此外,我想将逻辑和gui分开

比如,;我有两节课

  • SomeServices.swift,其方法名为“getDataFromService…”
  • MyTableViewController.swift将显示“getDataFromService”的结果
  • 因此,在前面的Objective-C中,我刚刚在一些服务中添加了一个方法,如下所示:

    (void)getDataFromService:(void (^)(NSArray *, NSError *))completionBlock{ ...... }
    
    在这个方法中,我刚刚调用了
    completionBlock(myData,myError)
    将我的值返回给tableviewcontroller

    我必须在SomeServices.swift中定义的等效闭包是什么?在MyTableViewController中如何调用它

    我知道如何调用这样一个简单的闭包:

       ....({
                responseData, error  in
                if(!error){
                    //Do something
                }
            })
    
    但我不知道如何用completionBlock等价物定义闭包


    任何帮助都将不胜感激

    闭包的好处是,您可以传递任何您想要的内容。方法或函数-这无关紧要

    您可以在参数内传递函数,然后调用它

    func someFunctionThatTakesAClosure(completionClosure: () -> ()) {
        // function body goes here
        if(error = false) {
           completionClosure()
        }
    
    }
    
    //Call it
    someFunctionThatTakesAClosure({
        //Completions Stuff
        println("someFunctionThatTakesAClosure")
    });
    

    摘自:苹果公司《Swift编程语言》。iBooks

    答案在语言指南中:

    假设您想要返回一个字符串。这就是语法

    ({(responseData: DataClass, error: ErrorClass) -> String in
    //do stuff - calculations etc..
    return calculatedString
    })
    
    下面是一个示例,它获取两个字符串并将它们连接起来,然后返回结果:

    let sumStrings = ({(first: String, second: String) -> String in
        return first + " " + second
    })
    
    然后您可以执行以下操作:

    sumStrings("Hello","Swift")             // "Hello Swift"
    

    下面是我如何使用singleton ServiceManager来实现这一点

    class ServiceManager: NSObject {
    
    //  Static Instance variable for Singleton
    static var sharedSessionManager = ServiceManager()
    
    //  Function to execute GET request and pass data from escaping closure
    func executeGetRequest(with urlString: String, completion: @escaping (Data?) -> ()) {
    
        let url = URL.init(string: urlString)
        let urlRequest = URLRequest(url: url!)
    
        URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
            //  Log errors (if any)
            if error != nil {
                print(error.debugDescription)
            } else {
                //  Passing the data from closure to the calling method
                completion(data)
            }
        }.resume()  // Starting the dataTask
    }
    
    //  Function to perform a task - Calls executeGetRequest(with urlString:) and receives data from the closure.
    func downloadMovies(from urlString: String, completion: @escaping ([Movie]) -> ()) {
        //  Calling executeGetRequest(with:)
        executeGetRequest(with: urlString) { (data) in  // Data received from closure
            do {
                //  JSON parsing
                let responseDict = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any]
                if let results = responseDict!["results"] as? [[String:Any]] {
                    var movies = [Movie]()
                    for obj in results {
                        let movie = Movie(movieDict: obj)
                        movies.append(movie)
                    }
                    //  Passing parsed JSON data from closure to the calling method.
                    completion(movies)
                }
            } catch {
                print("ERROR: could not retrieve response")
            }
        }
      }
    }
    
    下面是我如何使用singleton类的示例

    ServiceManager.sharedSessionManager.downloadMovies(from: urlBase) { (movies : [Movie]) in   // Object received from closure
    self.movies = movies
          DispatchQueue.main.async {
                //  Updating UI on main queue
                self.movieCollectionView.reloadData()
          }
    }
    

    我希望这能帮助任何寻找相同解决方案的人。

    Ha,我先查看了这本书,但完全忽略了这一个例子!谢谢你把它拔出来。正如上面所说的,如果闭包没有返回任何内容,
    ->()
    是必需的。