线程 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) func prepare
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) func prepare
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case toProductIdentifier: let destination = segue.destination as? ProductViewController
destination?.configureProduct(for: products[selectedRowIndex.row])
default: break
}
}
所以我在 destination?.configureProduct(for: products[selectedRowIndex.row])
行中收到此错误
这是 func configureProduct 的代码,但我真的不认为这个 func 有问题
func configureProduct(for product: instockProduct) {
DispatchQueue.main.async {
let brand = product.brand["name"] as? String ?? ""
self.productBrandLabel.text = brand.uppercased()
self.productNameLabel.text = product.name
self.productPriceLabel.text = product.price.stringValue
}
}
您正在用空值 indexPath = IndexPath()
实例化 indexPath
,并且可能没有使用 tableView 提供给您的 indexPath
,因此出现错误。我在 Playground 中用简化的示例复制了您的代码,但得到了同样的错误。
尝试检查 didSelectItemAt
函数是否被正确触发,您是否真正将 UITableView
返回的 indexPath 分配给 selectedRowIndex
变量,而不是使用预先创建的 IndexPath()
值.
问题是在 prepare(for segue
期间目标视图控制器中的出口尚未连接(尚未)。
您需要 ProductViewController
中的临时 属性 并在 viewDidLoad
中配置插座
var product : Product! // replace Product with the real type
func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.async {
let brand = product.brand["name"] as? String ?? ""
self.productBrandLabel.text = brand.uppercased()
self.productNameLabel.text = product.name
self.productPriceLabel.text = product.price.stringValue
}
}
并将prepare(for segue
替换为
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case toProductIdentifier:
let destination = segue.destination as! ProductViewController
let cell = sender as! ProductCollectionViewCell
let indexPath = collectionView.indexPath(for: cell)!
destination.product = products[indexPath.item]
default: break
}
}
编辑:
显然您将 cell 连接到 segue 而不是控制器。在这种情况下,cell
在 sender
参数中传递并且 didSelectItemAt
未被调用。删除 selectedRowIndex
并删除整个 didSelectItemAt
方法
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let product = products[indexPath.row]
print(product.name)
collectionView.deselectItem(at: indexPath, animated: true)
self.performSegue(withIdentifier: toProductIdentifier, sender: product)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case toProductIdentifier: let destination = segue.destination as? ProductViewController
destination?.configureProduct(for: products[selectedRowIndex.row])
default: break
}
}
所以我在 destination?.configureProduct(for: products[selectedRowIndex.row])
行中收到此错误这是 func configureProduct 的代码,但我真的不认为这个 func 有问题
func configureProduct(for product: instockProduct) {
DispatchQueue.main.async {
let brand = product.brand["name"] as? String ?? ""
self.productBrandLabel.text = brand.uppercased()
self.productNameLabel.text = product.name
self.productPriceLabel.text = product.price.stringValue
}
}
您正在用空值 indexPath = IndexPath()
实例化 indexPath
,并且可能没有使用 tableView 提供给您的 indexPath
,因此出现错误。我在 Playground 中用简化的示例复制了您的代码,但得到了同样的错误。
尝试检查 didSelectItemAt
函数是否被正确触发,您是否真正将 UITableView
返回的 indexPath 分配给 selectedRowIndex
变量,而不是使用预先创建的 IndexPath()
值.
问题是在 prepare(for segue
期间目标视图控制器中的出口尚未连接(尚未)。
您需要 ProductViewController
中的临时 属性 并在 viewDidLoad
var product : Product! // replace Product with the real type
func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.async {
let brand = product.brand["name"] as? String ?? ""
self.productBrandLabel.text = brand.uppercased()
self.productNameLabel.text = product.name
self.productPriceLabel.text = product.price.stringValue
}
}
并将prepare(for segue
替换为
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case toProductIdentifier:
let destination = segue.destination as! ProductViewController
let cell = sender as! ProductCollectionViewCell
let indexPath = collectionView.indexPath(for: cell)!
destination.product = products[indexPath.item]
default: break
}
}
编辑:
显然您将 cell 连接到 segue 而不是控制器。在这种情况下,cell
在 sender
参数中传递并且 didSelectItemAt
未被调用。删除 selectedRowIndex
并删除整个 didSelectItemAt
方法
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let product = products[indexPath.row]
print(product.name)
collectionView.deselectItem(at: indexPath, animated: true)
self.performSegue(withIdentifier: toProductIdentifier, sender: product)
}