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
}
}
我是 iOS 开发的新手,我发现了一个我无法克服的错误。我在网上和 Whosebug 上阅读了很多,但我不明白为什么这个错误不断出现。
在测试和做断点后,我认为我能够获得所需的数据
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
}
}