非强制解包问题

时间:2016-05-19 10:55:17

标签: arrays swift

我一直在发现同样的错误,导致XCode崩溃。我意识到在没有值的情况下搜索值时会发生这种情况。但是,每次尝试解决问题的尝试都会导致失败。

这是提示错误的代码行:

textFields[0].text = detail.valueForKey("moduleName") as? String 

VC:

class DetailViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate, UITextViewDelegate {

var tasks = [NSSet]() // sets list array for Task objects

var courseWork: CourseWork? {
    didSet {
        // Update the view.
        // do it in different thread cause some things take time to load...
        dispatch_async(dispatch_get_main_queue()) {
            self.configureView()
        }
    }
}

func configureView() { // Update the user interface for the detail view

    if let detail = self.courseWork { // if user clicks on a coursework/runs the app, then the UI is automatically updated:

        self.title = detail.valueForKey("courseWorkName")!.description // set title of navigation controller

        textFields[0].text = detail.valueForKey("moduleName") as? String //set UITtext field for module name - Optional ?

        textFields[1].text = detail.valueForKey("markAwarded") as? String // set UIText field for mark awarded - Optional ?

        if let level = detail.valueForKey("level")!.intValue { // setup slider for level and its label
            levelSlider.value = Float(level)
            levelLabel.text = "Level: \(level)"
        }


        if let value = detail.valueForKey("value")!.intValue { // setup slider for value and its label
            slider.value = Float(value)
            valueLabel.text = "Value: \(value)"
        }

        textView.text = detail.valueForKey("notes") as? String ?? "Enter Notes here..." //set UITtext field for task notes

        if let date = detail.valueForKey("dueDate") as? NSDate {
            datePicker.setDate(date, animated: true)
        }
    }
}


override func viewDidLoad() {
    super.viewDidLoad()

    reminderDatePicker.hidden = true

    textView.layer.borderWidth = 1
    textView.layer.borderColor = UIColor.blueColor().CGColor

    tableView.delegate = self
    tableView.dataSource = self
    tableView.estimatedRowHeight = tableView.rowHeight // dimensions
    tableView.rowHeight = UITableViewAutomaticDimension //hide blank cells in table view
    let backgroundView = UIView(frame: CGRectZero) // instantiating the view without an initial value for its frame
    tableView.tableFooterView = backgroundView // purpose is to automatically size the tableView depending on number of objects

    let addButton = UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "addNewTask") // "+" button is set as a button that adds tasks - addNewTask function is run
    self.navigationItem.rightBarButtonItem = addButton // sets position of addButton - at the right of the bar

    setupUIElements() // runs function

    // datePicker.addTarget(self, action: "datePickerValueChanged:", forControlEvents:.ValueChanged)
    datePicker.addTarget(self, action: "datePickerValueChanged:", forControlEvents: UIControlEvents.ValueChanged)

    //datePicker.addTarget(self, action: Selector("dataPickerChanged:"), forControlEvents: UIControlEvents.ValueChanged)


}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

//create alert with text field and create new item with that name
func addNewTask() {
    self.performSegueWithIdentifier("showTaskDetail", sender: nil)
}
// setting the delegate - start by checking the identifier of the segue, making sure we're preparing for the correct segue. We then ask the segue for its destination view controller - TaskDetailViewController
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let identifier = segue.identifier {
        if identifier == "showTaskDetail" {
            if let controller = segue.destinationViewController as? TaskDetailViewController {
                controller.courseWork = self.courseWork  // pass course work because of context
                if sender != nil { // some task is selected and sent to showDetail
                    controller.task = sender as? Task
                }
            }
        }
    }
}


//Table view for tasks

@IBOutlet weak var tableView: UITableView!


func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1 // only 1 section for the Task table view
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return tasks.count // the number of rows in table view is equal to the number of tasks
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("taskCell", forIndexPath: indexPath) as! TaskCustomCell // refers to outlet variable in TaskCustomCell class

    if let tasks = self.courseWork!.tasks {
        let allTasks = tasks.allObjects // add all Task objects to constant
        let task = allTasks[indexPath.row]
        if let name = task.valueForKey("taskName") as? String { // if name is entered for Task name
            cell.taskNameLabel.text = name // place value in UI Label
        }
    }

    return cell
}


func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    // Return false if you do not want the specified item to be editable.
    return true
}

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete { // enables the deleting of tasks
        if let tasks = self.courseWork!.tasks {
            let allTasks = tasks.allObjects // add all Task objects to constant
            let task = allTasks[indexPath.row] as! Task
            MasterViewController().deleteTask(task) // calls deleteTask function from Master View Controller
            NSNotificationCenter.defaultCenter().postNotificationName("updateDetailTableValues", object: nil) // updates task changes

        }
    }
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    //send task with the segue to destination so values can be edited
    if let tasks = self.courseWork!.tasks {
        let allTasks = tasks.allObjects // add all Task objects to constant
        let task = allTasks[indexPath.row]
        self.performSegueWithIdentifier("showTaskDetail", sender: task)

    }
}



//setup textField delegates for purpose of opening a new View - TaskDetailViewController
func setupUIElements() {

    //text fields
    for textF in textFields {
        textF.delegate = self
    }
    textView.delegate = self

}
//Text fields
@IBOutlet var textFields: [UITextField]!

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    if textField == textFields[0] { // module name field
        saveTHeCourseWork("moduleName", value: textFields[0].text!)
    } else if textField == textFields[1] { // mark awarded
        saveTHeCourseWork("markAwarded", value: textFields[1].text!)
    }
    return true
}

//text view - notes
@IBOutlet weak var textView: UITextView!

func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
    if text == "\n" { // if I see new line, or click Enter, I save it to Core Data
        saveTHeCourseWork("notes", value: textView.text) // selected value is saved as the value for "notes"
        textView.resignFirstResponder() // dismiss the xcode keyboard
    }
    return true
}

错误是:

  

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

0 个答案:

没有答案