Label.text 错误! - 在隐式展开可选值时意外发现 nil

Label.text Error! - Unexpectedly found nil while implicitly unwrapping an Optional value

我是 iOS 开发的新手,我发现了一个我无法克服的错误。我在网上和 Whosebug 上阅读了很多,但我不明白为什么这个错误不断出现。

在测试和做断点后,我认为我能够获得所需的数据问题是当我使用 uilabel 在屏幕上显示它时。

import UIKit

class ArtistViewController: UIViewController, artistViewModelDelegate {
    @IBOutlet weak var artwork: UIImageView!
    @IBOutlet weak var artistName: UILabel!
    @IBOutlet weak var albumName: UILabel!

    func loadArtistViewModel(data: ArtistViewModel) {
        guard let artistData = data as? ArtistViewModel else {}

        artistName.text = artistData.artistName //Unexpectedly found nil while unwrapping an Optional value
    }
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

希望大家能帮帮我,非常感谢!

编辑

ViewController ArtistViewController 的实例被调用的地方

import UIKit
import Alamofire
import SwiftyJSON

protocol artistViewModelDelegate {
    func loadArtistViewModel(data: ArtistViewModel)
}

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, artistSearchDelegate {
   
    @IBOutlet weak var tableView: UITableView!
    
    var data: [ArtistItem] = []
    var delegate: artistViewModelDelegate?
    var artistViewModel: ArtistViewModel?
    var params = [API_CONSTANTS.URL_TYPES.PARAMETERS.TERM: "Maroon 5",API_CONSTANTS.URL_TYPES.PARAMETERS.COUNTRY: API_CONSTANTS.AU, API_CONSTANTS.URL_TYPES.PARAMETERS.MEDIA: API_CONSTANTS.URL_TYPES.PARAMETERS.MUSIC]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.delegate = ArtistViewController()
        getItunesData()

        tableView.dataSource = self
        tableView.delegate = self
        tableView.register(UINib(nibName: "artistCell", bundle: nil), forCellReuseIdentifier: "artistCell")
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "artistCell", for: indexPath) as! artistCell

        cell.artistName.text = data[indexPath.row].artistName
        cell.albumName.text = data[indexPath.row].albumName
        cell.genre.text = data[indexPath.row].genre
        cell.trackPrice.text = "$\(String(data[indexPath.row].trackPrice))"
        cell.albumArtwork.load(url: data[indexPath.row].artwork)

        cell.layer.cornerRadius = 5
        cell.layer.masksToBounds = true
        
        return cell
    }
    //Mark: To Artist ViewController
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        artistViewModel = ArtistViewModel(artist: data[indexPath.row])
        let artistViewController = storyboard?.instantiateViewController(withIdentifier: "ArtistViewController") as! ArtistViewController

        delegate?.loadArtistViewModel(data: artistViewModel!)
        self.navigationController?.pushViewController(artistViewController, animated: true)
    }

    func getItunesData(){
        Alamofire.request(API_CONSTANTS.URL_TYPES.URL, method: .get, parameters: params).responseJSON
            { response in
            if response.result.isSuccess {
                let json = JSON(response.result.value)
                self.data = ArtistModel(json: json).artistItems
                self.tableView.reloadData()

            } else {
            }
        }
    }
    func didTapSearch(artist: String) {
        params = [API_CONSTANTS.URL_TYPES.PARAMETERS.TERM:"\(artist)"]
        getItunesData()
    }
    @IBAction func searchButton(_ sender: Any) {
        let popupSearchVC = storyboard?.instantiateViewController(withIdentifier: "popupSearchView") as! PopupViewController
        popupSearchVC.delegate = self
        present(popupSearchVC, animated: true, completion: nil)
    }
}

问题出在协议上。您将 delegate 设置为一个实例,该实例不是故事板中的实例。

但是使用给定的代码,您根本不需要协议。

删除

protocol artistViewModelDelegate {
   func loadArtistViewModel(data: ArtistViewModel)
} 

...

var delegate: artistViewModelDelegate?

...

self.delegate = ArtistViewController()

和协议一致性,然后替换

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    artistViewModel = ArtistViewModel(artist: data[indexPath.row])
    let artistViewController = storyboard?.instantiateViewController(withIdentifier: "ArtistViewController") as! ArtistViewController

    delegate?.loadArtistViewModel(data: artistViewModel!)
    self.navigationController?.pushViewController(artistViewController, animated: true)
}

   func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let artistViewController = storyboard?.instantiateViewController(withIdentifier: "ArtistViewController") as! ArtistViewController

    artistViewController.artistViewModel = ArtistViewModel(artist: data[indexPath.row])
    self.navigationController?.pushViewController(artistViewController, animated: true)
}   

并且在 ArtistViewController 中,您必须为模型使用临时变量,因为插座在实例化后(尚未)立即连接。

将问题中的代码替换为

import UIKit

class ArtistViewController: UIViewController, artistViewModelDelegate {
    @IBOutlet weak var artwork: UIImageView!
    @IBOutlet weak var artistName: UILabel!
    @IBOutlet weak var albumName: UILabel!

    var artistViewModel : ArtistViewModel!

    override func viewDidLoad() {
        super.viewDidLoad()
        artistName.text = artistViewModel.artistName
    }
}