意外发现Swift错误为nil,tableView和Firebase无法进行调试

时间:2016-12-24 17:36:39

标签: ios swift xcode debugging runtime-error

我已经用Google搜索并阅读了很多有关此主题的问题和答案,但我仍然无法解决我的问题。我有一个连接到firebase的项目,其中一个tableView连接到该信息。弹出以下错误:

  

在解包可选值时意外地发现了nil。

我已经检查了UIButton s,UILabel等之间的所有连接,并且最重要的是我尝试使用断点来查找错误。但是我似乎无法理解解决方案。来自项目的代码和消息以及错误:

@IBOutlet weak var addButton: UIBarButtonItem!
let listToUsers = "ListToUsers"
var backgroundNr = 0

var items: [GroceryItem] = []
let ref = FIRDatabase.database().reference(withPath: "grocery-items")
let usersRef = FIRDatabase.database().reference(withPath: "online")
var user: User!
var userCountBarButtonItem: UIBarButtonItem!
var counter = 1

override func viewDidLoad() {
super.viewDidLoad()

if user?.email == "tor@gmail.com" {
    addButton.isEnabled = false
}

tableView.allowsMultipleSelectionDuringEditing = false

userCountBarButtonItem = UIBarButtonItem(title: "1",
                                         style: .plain,
                                         target: self,
                                         action:   #selector(userCountButtonDidTouch))
userCountBarButtonItem.tintColor = UIColor.white
navigationItem.leftBarButtonItem = userCountBarButtonItem

usersRef.observe(.value, with: { snapshot in
  if snapshot.exists() {
    self.userCountBarButtonItem?.title = snapshot.childrenCount.description
  } else {
    self.userCountBarButtonItem?.title = "0"
  }
})

ref.queryOrdered(byChild: "completed").observe(.value, with: { snapshot in
 var newItems: [GroceryItem] = []

  for item in snapshot.children {
    let groceryItem = GroceryItem(snapshot: item as! FIRDataSnapshot)
    newItems.append(groceryItem)
  }

  self.items = newItems
  self.tableView.reloadData()
})

FIRAuth.auth()!.addStateDidChangeListener { auth, user in
  guard let user = user else { return }
  self.user = User(authData: user)
  let currentUserRef = self.usersRef.child(self.user!.uid)
  currentUserRef.setValue(self.user!.email)
  currentUserRef.onDisconnectRemoveValue()
}

}

  // MARK: UITableView Delegate methods


override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) as! SubjectTableViewCell
let groceryItem = items[indexPath.row]

if backgroundNr == 0 {
    cell.backgroundColor = UIColor(red: 222/255, green: 164/255, blue: 50/255, alpha: 0.6)
    backgroundNr += 1
} else {
    cell.backgroundColor = UIColor.white
    backgroundNr -= 1
  }

cell.textLabel?.text = groceryItem.name
cell.detailTextLabel?.text = groceryItem.addedByUser

toggleCellCheckbox(cell, isCompleted: groceryItem.completed)

return cell
}

override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}

override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
  let groceryItem = items[indexPath.row]
  groceryItem.ref?.removeValue()
 }
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let cell = tableView.cellForRow(at: indexPath) else { return }
let groceryItem = items[indexPath.row]
let toggledCompletion = !groceryItem.completed
toggleCellCheckbox(cell, isCompleted: toggledCompletion)
groceryItem.ref?.updateChildValues([
  "completed": toggledCompletion
])
}

func toggleCellCheckbox(_ cell: UITableViewCell, isCompleted: Bool) {
if !isCompleted {
  cell.accessoryType = .none
  cell.textLabel?.textColor = UIColor.black
  cell.detailTextLabel?.textColor = UIColor.black
} else {
  cell.accessoryType = .checkmark
  cell.textLabel?.textColor = UIColor.gray
  cell.detailTextLabel?.textColor = UIColor.gray
   }
   }


  // MARK: Add Item

 @IBAction func addButtonTapped(_ sender: Any) {

 let alert = UIAlertController(title: "Kunskaps Område",
                              message: "Lägg till objekt",
                              preferredStyle: .alert)

 let saveAction = UIAlertAction(title: "Spara",
                               style: .default) { _ in
                                // 1
                                guard let textField = alert.textFields?.first,
                                  let text = textField.text else { return }

                                // 2
                                let groceryItem = GroceryItem(name: text,
                                                              addedByUser: self.user!.email,
                                                              completed: false)
                                // 3
                                let groceryItemRef = self.ref.child(text.lowercased())

                                // 4
                                groceryItemRef.setValue(groceryItem.toAnyObject())
 }

let cancelAction = UIAlertAction(title: "Cancel",
                                 style: .default)

alert.addTextField()

alert.addAction(saveAction)
alert.addAction(cancelAction)

present(alert, animated: true, completion: nil)
}

func userCountButtonDidTouch() {
performSegue(withIdentifier: listToUsers, sender: nil)
}

@IBAction func startClockTapp(_ sender: Any) {

    Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(GroceryListTableViewController.updateCounter), userInfo: nil, repeats: true)



}

func updateCounter() {
    counter += 1

    let clock = String(counter)

    print(clock)
    let clockCurrent = Clock(name: clock, addedByUser: self.user!.email)
    let clockCurrentRef = self.ref.child(clock.lowercased())
    clockCurrentRef.setValue(clockCurrent.toAnyObject())


 } 

当使用断点来定位错误发生的位置时,它似乎位于以下函数中:(“UITable view delegate methods”中的第一行代码

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}

如果我使用断点错误,我现在不会,但如果它有帮助,那就是我得到的结果。

“杂货店”对象struct文件的代码如下:

import Foundation
import Firebase

struct GroceryItem {

let key: String
let name: String
let addedByUser: String
let ref: FIRDatabaseReference?
var completed: Bool

init(name: String, addedByUser: String, completed: Bool, key: String = "") {
    self.key = key
    self.name = name
    self.addedByUser = addedByUser
    self.completed = completed
    self.ref = nil
}

init(snapshot: FIRDataSnapshot) {
    key = snapshot.key
    let snapshotValue = snapshot.value as! [String: AnyObject]
    name = snapshotValue["name"] as! String
    addedByUser = snapshotValue["addedByUser"] as! String
    completed = snapshotValue["completed"] as! Bool
    ref = snapshot.ref
}

func toAnyObject() -> Any {
    return [
        "name": name,
        "addedByUser": addedByUser,
        "completed": completed
    ]
}

}

Firebase上的数据库内容结构如下:

  1. educationlevel-e230e

  2. 杂货项

  3. Fysik:,addedByUser:,已完成:
  4. 基本错误消息的完整字符串:

      

    致命错误:在展开Optional值时意外发现nil   2016-12-24 01:22:54.799117 EducationLevel [1077:263810]

         

    致命错误:   在展开可选值时意外发现nil

    我真的无法通过我自己或网络上的任何地方找到这个问题的答案,真的很感激,如果我能得到一些帮助(对不起英语可能不好,我来自瑞典;)) p>

    (如果您需要更多来自错误消息或类似内容的字符串,我会立即更新此问题)

    谢谢!来自瑞典的Tor。

0 个答案:

没有答案