简体   繁体   English

在强制展开可选的swift 2时发现nil

[英]Found nil while force unwrapping an optional swift 2

I keep getting an error saying found nil while unwrapping optional value. 我不断收到错误消息,指出在展开可选值时发现了nil。 I don't know why it does this as data is stored to the variable from another view controller, but it doesn't assign a new value but keeps it at nil. 我不知道为什么要这样做,因为数据是从另一个视图控制器存储到变量的,但是它没有分配新值,而是保持为零。 Why is it doing this? 为什么这样做呢? Any help would be greatly appreciated thanks. 任何帮助将不胜感激谢谢。

Note: It crashes on line 47 of userEventViewController 注意:它在userEventViewController的第47行崩溃

Crashes on Line: myTitle.title = event!.name 在线崩溃:myTitle.title = event!.name

Link to project: https://www.dropbox.com/s/1d4d8opuxzpcuk4/TicketekApp.zip?dl=0 链接到项目: https : //www.dropbox.com/s/1d4d8opuxzpcuk4/TicketekApp.zip?dl=0

Code: 码:

source view controller (EventTableViewController): 源视图控制器(EventTableViewController):

//  EventTableViewController.swift



import UIKit

class EventTableViewController: UITableViewController {
// MARK: Properties
var currentlySelectedIndex = 0
var events = [Event]()
var isAdmin: Bool = false
var currentUser: String = ""
override func viewDidLoad() {
    super.viewDidLoad()
    print(currentUser)
    // Use the edit button item provided by the table view controller.
    if isAdmin == true {
    navigationItem.leftBarButtonItem = editButtonItem()
    }
    // Load any saved events, otherwise load sample data.
    if let savedEvents = loadEvents() {
        events += savedEvents
    } else {
        // Load the sample data.
        loadSampleEvents()
    }
}

func loadSampleEvents() {
    let photo1 = UIImage(named: "event1")!
    let event1 = Event(name: "ACDC", photo: photo1, rating: 4, price: 100.0, eventDescription: "AC/DC are an Australian hard rock band, formed in November 1973 by brothers Malcolm and Angus Young, who continued as members until Malcolm's illness and departure in 2014. Date of Event: 1/3/16", album: "Redemption Tour")!

    let photo2 = UIImage(named: "event2")!
    let event2 = Event(name: "Cold Play", photo: photo2, rating: 5, price: 150.0, eventDescription: "Coldplay are a British rock band formed in 1996 by lead vocalist Chris Martin and lead guitarist Jonny Buckland at University College London. Date of Event: 12/12/15", album: "Mylo Xyloto")!

    let photo3 = UIImage(named: "event3")!
    let event3 = Event(name: "One Direction", photo: photo3, rating: 3, price: 120.0, eventDescription: "One Direction are an English-Irish pop boy band based in London, composed of Niall Horan, Liam Payne, Harry Styles, Louis Tomlinson, and previously, Zayn Malik until his departure from the band on 25 March 2015. Date of Event: 5/9/16", album: "Made in the A.M.")!

    events += [event1, event2, event3]
}

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

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

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

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    // Table view cells are reused and should be dequeued using a cell identifier.
    let cellIdentifier = "EventTableViewCell"
    let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! EventTableViewCell

    // Fetches the appropriate event for the data source layout.
    let event = events[indexPath.row]

    cell.nameLabel.text = event.name
    cell.photoImageView.image = event.photo
    cell.ratingControl.rating = event.rating
    cell.priceLabel.text = event.album

    return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    //Record the row selected
    currentlySelectedIndex = indexPath.row

    //check for admin
    if isAdmin == true {
        performSegueWithIdentifier("eventViewControllerSegue", sender: self)
    } else {
        performSegueWithIdentifier("userEventViewControllerSegue", sender: self)
    }
}

// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    // Return false if you do not want item to be editable.
    if isAdmin == true {
    return true
    } else {
        return false
    }
}


// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if isAdmin == true {
    if editingStyle == .Delete {
        // Delete the row from the data source
        events.removeAtIndex(indexPath.row)
        saveEvents()
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
    } else if editingStyle == .Insert {
        // Create new instance of  class, add to the array, and add a new row to the table
    }
    }
}


/*
// Override to support rearranging the table view.
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {

}
*/


// Override to support conditional rearranging of the table view.
override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
    if isAdmin == true {
return true
    } else {
        return false
    }
}



// MARK: - Navigation

// preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "eventViewControllerSegue"  {
        let destinationVC1 = segue.destinationViewController as? EventViewController
        destinationVC1!.event = events[currentlySelectedIndex]
    } else  if segue.identifier == "userEventViewControllerSegue"  {
        let eventDetailViewController = segue.destinationViewController as! UserEventViewController
        //Get the associated event
        eventDetailViewController.event = events[currentlySelectedIndex]
        let destinationVC = segue.destinationViewController as? UserEventViewController
            destinationVC!.event = events[currentlySelectedIndex]
            destinationVC!.currentUser = currentUser

    }
    else if segue.identifier == "AddItem" {
        print("Adding new event.")
    }
}

@IBAction func unwindToMealList(sender: UIStoryboardSegue) {
    if let sourceViewController = sender.sourceViewController as? EventViewController, event = sourceViewController.event {
        if let selectedIndexPath = tableView.indexPathForSelectedRow {
            // Update an existing event.
            events[selectedIndexPath.row] = event
            tableView.reloadRowsAtIndexPaths([selectedIndexPath], withRowAnimation: .None)
        } else {
            // Add a new event.
            let newIndexPath = NSIndexPath(forRow: events.count, inSection: 0)
            events.append(event)
            tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Bottom)
        }
        // Save the events.
        saveEvents()
    }
}

// MARK: NSCoding

func saveEvents() {
    let isSuccessfulSave = NSKeyedArchiver.archiveRootObject(events, toFile: Event.ArchiveURL.path!)
    if !isSuccessfulSave {
        print("Failed to save events...")
    }
}

func loadEvents() -> [Event]? {
    return NSKeyedUnarchiver.unarchiveObjectWithFile(Event.ArchiveURL.path!) as? [Event]
}
}

destination view controller (userEventViewController): 目标视图控制器(userEventViewController):

//  EventViewController.swift



import UIKit

class UserEventViewController: UIViewController {
// MARK: Properties










@IBOutlet weak var eventDescriptionLabel: UITextView!

@IBOutlet weak var priceLabel: UILabel!

@IBOutlet weak var nameLabel: UILabel!

@IBOutlet weak var photoImageView: UIImageView!

@IBOutlet weak var albumNameLabel: UILabel!

@IBOutlet weak var myTitle: UINavigationItem!

@IBOutlet weak var ratingControl: RatingControl!

var event: Event?
var currentUser: String = ""





override func viewDidLoad() {
    super.viewDidLoad()


    // Set up views if editing an existing event.
    //                        |
    // Crashes on this line  \./
        myTitle.title = event!.name
        nameLabel.text   = event!.name
        photoImageView.image = event!.photo
        ratingControl.rating = event!.rating
        eventDescriptionLabel.text = event!.eventDescription
        albumNameLabel.text = event!.album
        priceLabel.text = String(event!.price)
        print(currentUser)

    }



@IBAction func buyTickets(sender: AnyObject) {
    performSegueWithIdentifier("BuyTickets", sender: self)
}



override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "BuyTickets" {
        let destinationVC = segue.destinationViewController as? seatsPickerViewController
            destinationVC!.price = event!.price
            destinationVC!.name = event!.name
            destinationVC!.album = event!.album
            destinationVC!.photo = event!.photo
            destinationVC!.currentUser = currentUser

                }

}


}

You have not connected your outlet: 您尚未连接插座: 在此处输入图片说明

It will crash because you haven't initialised event . 它会崩溃,因为您尚未初始化event You just declared it to be an optional, so it holds nil when you choose to unwrap it a few lines later. 您刚刚声明它是可选的,因此当您选择在稍后几行解开包装时,它为nil。 And as we know, if you try to unwrap nil, your program crashes. 并且我们知道,如果您尝试解开nil,则程序将崩溃。

Give a value to event and then try event赋值,然后尝试

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM