嘿,我每次單擊表格視圖中的任何單元格時都會出現“執行緒 1:致命錯誤:索引超出范圍”(在這一行中 selectedId = idArray[indexPath.row] )錯誤。我該如何解決這個問題。我想我的陣列有問題,但我想不通。我在上一個應用程式中做了同樣的事情,但它沒有得到任何錯誤。
import UIKit
import CoreData
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
var nameArray = [String]()
var idArray = [UUID?]()
var selectedName = ""
var selectedId : UUID?
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
navigationController?.navigationBar.topItem?.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.add, target: self, action: #selector(addNewPatient))
getData()
}
override func viewWillAppear(_ animated: Bool) {
NotificationCenter.default.addObserver(self, selector: #selector(getData) , name: NSNotification.Name(rawValue: "newData"), object: nil)
}
@objc func getData() {
nameArray.removeAll(keepingCapacity: false)
idArray.removeAll(keepingCapacity: false)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "ToName")
fetchRequest.returnsObjectsAsFaults = false
do {
let results = try context.fetch(fetchRequest)
if results.count > 0 {
for result in results as! [NSManagedObject] {
if let name = result.value(forKey: "name") as? String {
self.nameArray.append(name)
}
if let id = result.value(forKey: "id") as? UUID {
self.idArray.append(id)
}
}
}
} catch {
print("error")
}
tableView.reloadData()
}
@objc func addNewPatient() {
selectedName = ""
performSegue(withIdentifier: "toNameVC", sender: nil)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return nameArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
var content = cell.defaultContentConfiguration()
content.text = nameArray[indexPath.row]
// content.secondaryText = "secondary test"
cell.contentConfiguration = content
return cell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toNameVC" {
let destinationVC = segue.destination as! ToNameViewController
destinationVC.choosenName = selectedName
destinationVC.choosenId = selectedId
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedName = nameArray[indexPath.row]
selectedId = idArray[indexPath.row]
performSegue(withIdentifier: "toNameVC", sender: nil)
}
}
這是我的 toNameViewController.swift 頁面
ToNameViewController.swift
Patient Record App
import UIKit
import CoreData
class ToNameViewController: UIViewController {
@IBOutlet weak var nameLabelText: UITextField!
@IBOutlet weak var tcLabelText: UITextField!
@IBOutlet weak var birthDateLabelText: UITextField!
var choosenName = ""
var choosenId : UUID?
override func viewDidLoad() {
super.viewDidLoad()
if choosenName != "" {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "ToName")
let idString = choosenId?.uuidString
fetchRequest.predicate = NSPredicate(format: "id = %@", idString!)
fetchRequest.returnsObjectsAsFaults = false
do {
let results = try context.fetch(fetchRequest)
if results.count > 0 {
for result in results as! [NSManagedObject] {
if let name = result.value(forKey: "name") as? String {
nameLabelText.text = name
}
if let tc = result.value(forKey: "tc") as? Int {
tcLabelText.text = String(tc)
}
if let birth = result.value(forKey: "birth") as? Int {
birthDateLabelText.text = String(birth)
}
}
}
} catch {
print("error")
}
}else {
}
let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(hiddenKeyboard))
view?.addGestureRecognizer(gestureRecognizer)
}
@objc func hiddenKeyboard() {
view?.endEditing(true)
}
@IBAction func saveButton(_ sender: Any) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let newPatient = NSEntityDescription.insertNewObject(forEntityName: "ToName", into: context)
newPatient.setValue(nameLabelText.text, forKey: "name")
if let tc = Int(tcLabelText.text!) {
newPatient.setValue(tc, forKey: "tc")
}
if let birth = Int(birthDateLabelText.text!) {
newPatient.setValue(birth, forKey: "birth")
}
do {
try context.save()
print("saved")
} catch {
print("error")
}
NotificationCenter.default.post(name: NSNotification.Name("newData"), object: nil)
self.navigationController?.popViewController(animated: true)
}
}
uj5u.com熱心網友回復:
這是一個常見的錯誤:如果兩個陣列都填充了可選項,則資料源的多個陣列極易出錯。
宣告一個自定義結構
struct Item {
let name: String
let id: UUID?
}
宣告資料源
var items = [Item]()
填充陣列(valueForKey語法已過時)
let fetchRequest = NSFetchRequest<ToName>(entityName: "ToName")
fetchRequest.returnsObjectsAsFaults = false
do {
let results = try context.fetch(fetchRequest)
for result in results {
if let name = result.name {
self.items.append(Item(name: name, id: result.id))
}
}
tableView.reloadData()
} catch {
print(error)
}
在numberOfRowsInSection
return items.count
在cellForRowAt
content.text = items[indexPath.row].name
而在didSelectRowAt
let item = items[indexPath.row]
selectedName = item.name
selectedId = item.id
您甚至可以將Item實體傳遞給第二個視圖控制器而不是兩個selected...屬性。
但為什么連
var toNames = [ToName]()
這避免了任何超出范圍的崩潰
uj5u.com熱心網友回復:
在你的getData函式中,你將值附加到idArray. Butresult.value(forKey: "id")是可選的,除非是nil. nameArray因此和之間的計數可能存在差異idArray。因此,如果result.value(forKey: "id")為 nil,則將默認值附加到idArray.
@objc func getData() {
nameArray.removeAll(keepingCapacity: false)
idArray.removeAll(keepingCapacity: false)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "ToName")
fetchRequest.returnsObjectsAsFaults = false
do {
let results = try context.fetch(fetchRequest)
if results.count > 0 {
for result in results as! [NSManagedObject] {
if let name = result.value(forKey: "name") as? String {
self.nameArray.append(name)
//change here like this
if let id = result.value(forKey: "id") as? UUID {
self.idArray.append(id)
}else{
self.idArray.append("your_default_value")//default value or nil
}
}
}
} catch {
print("error")
}
tableView.reloadData()
}
uj5u.com熱心網友回復:
向陣列添加擴展:
extension Array {
func object(at index: Int) -> Element? {
if index < count {
return self[index]
} else {
return nil
}
}
}
現在,只要您訪問陣列中的元素,就使用此方法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/515078.html
標籤:IOS迅速代码合适的视图
