这个函数正确吗?使用闭包调用函数(swift-iOS) 问题

这个函数正确吗?使用闭包调用函数(swift-iOS) 问题,ios,json,swift,api,alamofire,Ios,Json,Swift,Api,Alamofire,我必须在API上搜索一部电影,然后在我的表视图中返回搜索的电影 语言 Swift 3-xcode 8 函数从API获取Json 然后,我的刀: class MovieDAO { //Search By Title static func getMovies(imdbTitle: String, completionHandler: @escaping (([Movie]) -> ())) { searchMoviesOnJson(imdbTitle: imdbTitle,

我必须在API上搜索一部电影,然后在我的表视图中返回搜索的电影

语言 Swift 3-xcode 8

函数从API获取Json 然后,我的刀:

class MovieDAO {


//Search By Title

static func getMovies(imdbTitle: String, completionHandler: @escaping (([Movie]) -> ())) {

    searchMoviesOnJson(imdbTitle: imdbTitle, completionHandler: {
      newMoviesJSON in

        if let moviesJSON = newMoviesJSON {

            if moviesJSON["Error"] != nil { return }

            else {

                //casting
                let arrayOfMovies: [[String : String]] = newMoviesJSON!["Search"] as! [[String : String]]

                var fetchedMovies = [Movie]()

                for eachFetchedMovie: [String : String] in arrayOfMovies {

                    var poster: String?
                    var title : String?
                    var year  : String?
                    var imdbID: String?

                    if let isPoster = eachFetchedMovie["Poster"] { poster = isPoster }
                    else { poster = nil }

                    if let isTitle = eachFetchedMovie["Title"] { title = isTitle }
                    else { title = nil }

                    if let isYear = eachFetchedMovie["Year"] { year = isYear }
                    else { year = nil }

                    if let isImdbID = eachFetchedMovie["imdbID"] { imdbID = isImdbID }
                    else { imdbID = nil }

                    let movie: Movie = Movie(poster: poster, title: title, year: year, imdbID: imdbID)

                    fetchedMovies.append(movie)

                }
                completionHandler(fetchedMovies)
            }

        }

    })

  }
}
首先,什么是闭包?如果我不在这个函数中使用闭包,会发生什么

现在,我如何测试这个函数?我在AppDelegate中将其称为:

print(MovieDAO.getMovies(imdbTitle: "arq"))
但是xcode返回一个错误,表示调用中缺少一个参数。那么,你能给我解释一下吗?我读过,但我是一个初学者,它仍然让我困惑

哦,我想打印一个带有搜索标题的数组。我几乎可以肯定,我的函数不会返回这个值。我如何调整功能以实现这一点

为了更好地理解,API为搜索的电影提供了以下Json:

{
Response = True;
Search =     (
            {
        Poster = "https://images-na.ssl-images-amazon.com/images/M/MV5BMjAxODQ2MzkyMV5BMl5BanBnXkFtZTgwNjU3MTE5OTE@._V1_SX300.jpg";
        Title = ARQ;
        Type = movie;
        Year = 2016;
        imdbID = tt5640450;
    },
            {
        Poster = "N/A";
        Title = Arq;
        Type = movie;
        Year = 2011;
        imdbID = tt2141601;
    },
            {
        Poster = "N/A";
        Title = "A.R.Q.";
        Type = movie;
        Year = 2015;
        imdbID = tt3829612;
    }
);
totalResults = 3;
}
更新1: 我确实喜欢这个建议,并调用(在我的AppDelegate上,只是为了测试,看看它是否得到了我想要的,在本例中,是一个电影列表,其中包含标题上的“arq”)我的函数,如下所示:

MovieDAO.getMovies(imdbTitle: "arq") {
        (movies: [Movie]) in
        // Do something with the movies
        print(movies)
    }
返回的是此错误:


这条绿色的线怎么了?

问题出在哪里

您尝试调用的函数具有如下方法签名:

getMovies(imdbTitle:String,completionHandler:@escaping(([Movie])->())

您正试图仅使用第一个参数调用它:
imdbTitle
。您看到的错误是因为您从未传入完成处理程序-您缺少最后一个参数

解决方案

更改呼叫以包含完成块,如下所示:

MovieDAO.getMovies(imdbTitle: "Title") {
  (movies: [Movie]) in
  // Do something with the movies
  print(movies)
}

问题

您尝试调用的函数具有如下方法签名:

getMovies(imdbTitle:String,completionHandler:@escaping(([Movie])->())

您正试图仅使用第一个参数调用它:
imdbTitle
。您看到的错误是因为您从未传入完成处理程序-您缺少最后一个参数

解决方案

更改呼叫以包含完成块,如下所示:

MovieDAO.getMovies(imdbTitle: "Title") {
  (movies: [Movie]) in
  // Do something with the movies
  print(movies)
}

可以将闭包看作是一组要运行的代码,保存为变量,然后传递给函数

这就是您在MoviesDAO内的GetMovies函数调用中所做的

static func getMovies(imdbTitle: String, completionHandler: @escaping (([Movie]) -> ())) {
completionHandler参数需要一个代码块,该代码块接受电影对象数组并对其执行某些操作。(可能在您的箱子中打印)

因为,现在发生的事情是,你在问一些API(IMDB),“嘿,我想让你给我一堆名为‘arg’的电影”。IMDB无法立即提供该信息,并且您不希望程序的其余部分等待,因此GetMovies函数调用要求在获取movie对象数组后运行一些代码

completionHandler(fetchedMovies)
您对函数参数的命名也有点混乱,这可能对您正在阅读的内容没有帮助。您的名字与SearchMoviesOnJSON函数的completionHandler有冲突。所以我将重命名您的getMovies函数,但不要使用SearchMoviesOnJSON

static func getMovies(imdbTitle: String, handlerForMovieArray: @escaping (([Movie]) -> ()))
因此,与其打电话

print(MovieDAO.getMovies(imdbTitle: "arq"))
您应该做的是定义一个闭包(一段代码),getMovies函数在最后调用该闭包

MovieDAO.getMovies(imdbTitle: "arg", handlerForMovieArray: {
    MoviesList in //<-- This is your input. 
    //Your array of movies that is being passed by the call to "handlerForMovieArray"

    //Do some fancy code stuff here. Probably want to loop over MoviesList and print the values you want
})
MovieDAO.getMovies(imdbTitle:“arg”,handlerForMovieArray:{

//中的MoviesList将闭包视为一组要运行的代码,并将其保存为变量,然后传递给函数

这就是您在MoviesDAO内的GetMovies函数调用中所做的

static func getMovies(imdbTitle: String, completionHandler: @escaping (([Movie]) -> ())) {
completionHandler参数需要一个代码块,该代码块接受一个电影对象数组并对其进行处理(在您的示例中可能是打印)

因为,现在发生的事情是,你问一些API(IMDB),“嘿,我想让你给我一堆名为‘arg’的电影”.IMDB无法立即向您提供该信息,并且您不希望程序的其余部分等待,因此GetMovies函数调用要求在获取电影对象数组后运行一些代码

completionHandler(fetchedMovies)
您对函数参数的命名也有点混乱,这可能对您阅读的内容没有帮助。您的名字与SearchMoviesOnJSON函数的completionHandler有冲突。因此,我将重命名您的getMovies函数,但不要使用SearchMoviesOnJSON

static func getMovies(imdbTitle: String, handlerForMovieArray: @escaping (([Movie]) -> ()))
因此,与其打电话

print(MovieDAO.getMovies(imdbTitle: "arq"))
您应该做的是定义一个闭包(一段代码),getMovies函数在最后调用该闭包

MovieDAO.getMovies(imdbTitle: "arg", handlerForMovieArray: {
    MoviesList in //<-- This is your input. 
    //Your array of movies that is being passed by the call to "handlerForMovieArray"

    //Do some fancy code stuff here. Probably want to loop over MoviesList and print the values you want
})
MovieDAO.getMovies(imdbTitle:“arg”,handlerForMovieArray:{

MoviesList in//shorn your code,only put main thingsclosure用于回调,而我们从服务器或任何其他相同的用途得到响应。您想做什么?@KKRocks我有一个带有搜索栏的表视图。我想做的是:用户在搜索栏上键入一个imdbTitle,我的表视图根据API给出的响应显示结果me(如此JSON文件)。表视图将显示my getMovies函数的返回。请收缩代码,只有put main thingsclosure用于回调,而我们从服务器获得响应或任何其他相同用途。您想做什么?@KKRocks我有一个带有搜索栏的表视图。我想做的是:用户在搜索栏上键入imdbTitle,我的表视图显示结果根据API给我的响应(如此JSON文件)。表视图将显示我的getMovies函数的返回。非常好的解释,谢谢。我这样做了:MovieDAO.getMovies(imdbTitle:“arq”){(movies:[Movie])in//Do something with the movies print(movies)}但当我运行时,应用程序崩溃。在控制台上只返回一个(lldb)。这意味着什么?在我的MovieDAO上,它的一行是绿色的(见我问题中更新的图片)。我没有想法。就像我说的,我是一个新手,做了以下事情