有没有一种方法可以在另一个范围内使用我的Music类型数组?

时间:2018-07-11 00:08:44

标签: swift

我试图在创建它的函数之外打印/转储和类型Music类型的数组。我可以成功将转储musicItems数组到getMusicData函数内部,但是当我在范围之外设置musicItems数组时,它会成功什么都不打印。我的示波器在做什么呢?我觉得它非常简单,但我无法弄清楚。在此先感谢您抽出宝贵的时间阅读本文。

edit:当我尝试将ViewItem类中的musicItems数组转储时,它在控制台中给了我“ 0个元素”。好吧,该函数也位于同一类中,所以我想我不知道该如何调用第一个数组。父数组?<​​/ p>

struct MusicResults: Decodable {
    let results: [Music]?
}

struct Music: Decodable {
    let trackName: String?
    let collectionName: String?
    let artworkUrl30: String?

    }


class ViewController: UITableViewController, UISearchBarDelegate  {

    var musicItems: [Music] = []

    @IBAction func musicButton(_ sender: UIBarButtonItem) {
        getMusicData()
        dump(musicItems)

    }

这是功能。

func getMusicData() {
        var musicItems: [Music] = []
        guard let searchTerm = searchString else {return}
        let newString = searchTerm.replacingOccurrences(of: " ", with: "+", options: .literal, range: nil)
        let jsonUrlString = "https://itunes.apple.com/search?media=music&term=\(newString)"
        guard let url = URL(string: jsonUrlString) else { return }

        URLSession.shared.dataTask(with: url) { (data, response, err) in

            guard let data = data else { return }


            do {


                let music = try JSONDecoder().decode(MusicResults.self, from: data)
                for results in music.results! {
//                    print(results.trackName!)
                    musicItems.append(results)
                }
                //dump(musicItems)
                self.musicItems = musicItems
//                DispatchQueue.main.async {
//                    self.tableView.reloadData()
//                }



            } catch let jsonErr {
                print("Error serializing json:", jsonErr)
            }



            }.resume()


    }

固定代码

@IBAction func musicButton(_ sender: UIBarButtonItem) {
    getMusicData {
        music in
        dump(music)
    }

功能:

 func getMusicData(completionHandler: @escaping (_ music: [Music]) -> ()) {

...


 let music = try JSONDecoder().decode(MusicResults.self, from: data)
                for results in music.results! {
                    musicItems.append(results)
                }
                completionHandler(musicItems)

...

2 个答案:

答案 0 :(得分:1)

您的'getMusicData'函数是异步的,这意味着它在执行时会将数据任务排队在后台队列中并继续执行,并且由于没有更多的机构,它只是将控制权返回给其调用站点-'musicButton()'动作又执行下一条指令-打印“ musicItems”数组,由于网络调用尚未完成,该数组可能(很可能)仍未填充。您可以在其中执行的一种选择是将完成代码块传递给“ getMusicData”函数,该函数在数据任务获得结果后运行。

答案 1 :(得分:1)

另一种选择是使用Property Observers

var musicItems: [Music] = [] {
    didSet {
        dump(self.musicItems)
/// This is where I would do the...
//            DispatchQueue.main.async {
//                self.tableView.reloadData()
//            }
    }
}

然后

func getMusicData() {
    guard let searchTerm = searchString else { print("no search"); return }
    let newString = searchTerm.replacingOccurrences(of: " ", with: "+", options: .literal, range: nil)
    let jsonUrlString = "https://itunes.apple.com/search?media=music&term=\(newString)"
    guard let url = URL(string: jsonUrlString) else { print("url error"); return }
    URLSession.shared.dataTask(with: url) { (data, response, err) in
        guard let data = data else { print(err ?? "unknown"); return }
        do {
            let music = try JSONDecoder().decode(MusicResults.self, from: data)
            if let results = music.results {
                self.musicItems.append(contentsOf: results)
            }
        } catch let jsonErr {
            print("Error serializing json:", jsonErr)
        }
    }.resume()
}