加载 tableView 时打开可选值时意外发现 nil

Posted

技术标签:

【中文标题】加载 tableView 时打开可选值时意外发现 nil【英文标题】:Unexpectedly found nil while unwrapping an optional value when loading tableView 【发布时间】:2016-09-02 14:56:10 【问题描述】:

我在堆栈上已经有一段时间了,但从来不需要问问题,因为我总是在搜索后找到答案,但现在我真的被困住了。我一直在四处寻找并通过一些试验和错误来寻找答案,但我一直遇到同样的错误。我基本上是在屏幕的下半部分制作一个带有 tableView 的个人资料页面。上半部分正在加载细填当前用户的信息。与视图控制器和单元视图控制器的所有连接似乎都很好。但是,表格视图将在加载时显示没有数据并崩溃并出现致命错误:

在展开可选值时意外发现 nil。

我也相信 cellForRowAtIndexPath 根本没有被调用,因为“测试”没有打印到日志中。

我正在使用最新版本的 Swift 和 Parse。

我对 swift 比较陌生,所以我会继续在这里发布我的整个代码,如果有任何帮助,我们将不胜感激。

import UIKit
import Parse
import ParseUI

class profileViewController: UIViewController, UITableViewDelegate, UITableViewDataSource 


@IBOutlet var tableView: UITableView!
@IBOutlet var profilePic: UIImageView!
@IBOutlet var userName: UILabel!
@IBOutlet var userBio: UILabel!
var image: PFFile!
var username = String()
var userbio = String()
var content = [String]()


@IBAction func logout(sender: AnyObject) 
    PFUser.logOut()
    let Login = storyboard?.instantiateViewControllerWithIdentifier("ViewController")
    self.presentViewController(Login!, animated: true, completion: nil)



override func viewDidLoad() 
    super.viewDidLoad()


    profilePic.layer.borderWidth = 1
    profilePic.layer.masksToBounds = false
    profilePic.layer.borderColor = UIColor.blackColor().CGColor
    profilePic.layer.cornerRadius = profilePic.frame.height/2
    profilePic.clipsToBounds = true


    tableView.delegate = self
    tableView.dataSource = self


    self.tableView.rowHeight = 80


    self.hideKeyboardWhenTappedAround()

    if let nameQuery = PFUser.currentUser()!["name"] as? String 
        username = nameQuery
    

    if PFUser.currentUser()!["bio"] != nil 
    if let bioQuery = PFUser.currentUser()!["bio"] as? String 
        userbio = bioQuery
    
    

    if PFUser.currentUser()!["icon"] != nil 
    if let iconQuery = PFUser.currentUser()!["icon"] as? PFFile 
        image = iconQuery
    
    



    self.userName.text = username
    self.userBio.text = userbio

    if image != nil 
    self.image.getDataInBackgroundWithBlock  (data, error) -> Void in


        if let downIcon = UIImage(data: data!) 


            self.profilePic.image = downIcon

        
        

    


    // Do any additional setup after loading the view.

    var postsQuery = PFQuery(className: "Posts")

    postsQuery.whereKey("username", equalTo: username)

    postsQuery.findObjectsInBackgroundWithBlock(  (posts, error) -> Void in

        if error == nil 

            if let objects = posts 
                self.content.removeAll(keepCapacity: true)

                for object in objects 
                    if object["postText"] != nil 
                        self.content.append(object["postText"] as! String)
                    
                    self.tableView.reloadData()
                
            
        

    )






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



func numberOfSectionsInTableView(tableView: UITableView) -> Int 
    // #warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1


func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    // #warning Incomplete method implementation.
    // Return the number of rows in the section.
    print(content.count)
    return content.count


func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    let profCell = self.tableView.dequeueReusableCellWithIdentifier("profCell", forIndexPath: indexPath) as! profTableViewCell

    print("test")

    profCell.userPic.layer.borderWidth = 1
    profCell.userPic.layer.masksToBounds = false
    profCell.userPic.layer.borderColor = UIColor.blackColor().CGColor
    profCell.userPic.layer.cornerRadius = profCell.userPic.frame.height/2
    profCell.userPic.clipsToBounds = true


    profCell.userPic.image = self.profilePic.image
    profCell.name.text = self.username




    profCell.content.text = content[indexPath.row]



    return profCell



【问题讨论】:

您似乎没有在 UIViewController 代码中注册您的自定义 UITableViewCell 类? 尽可能更新屏幕截图,以防止出现此类错误,如果让 mvar = yourvariable 或确保您正确绑定 tableview 插座并委托和数据源 崩溃在哪一行? @acorc 它必须在使用强制解包的出队。可能只需要: self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "someCustomCell") @Woodstock 假设他没有在情节提要中注册带有该标识符的原型单元(他在顶部有插座)我同意。这就是我停止使用 Storyboard 的原因,太多的晦涩难懂使得追查问题变得困难。 【参考方案1】:

我让它坐了几天,然后我回来意识到我犯了一个非常愚蠢的错误。我现在使用大约 15 个视图控制器,并意识到我有一个与上面发布的同名视图控制器的副本。我现在明白为什么你说使用故事板非常棘手。虽然,我不需要它,但我很感激你的帮助,我可以说我学到了一些东西。

【讨论】:

【参考方案2】:

您可能需要为自定义 UITableViewCell 注册您正在使用的类:

self.tableView.registerClass(profTableViewCell.self, forCellReuseIdentifier: "profCell") 

除非您在 IB 中使用原型单元,否则此注册不会自动为您完成。

因此,当您调用 dequeue 方法(使用 ! 强制展开)时,您将遇到问题。 dequeueReusableCellWithIdentifier:forIndexPath: 断言如果您没有为标识符注册类或 nib。 当您注册课程时,这总是返回一个单元格。

在这种情况下,较旧的 (dequeueReusableCellWithIdentifier:) 版本返回 nil,然后您可以创建自己的单元格。

您应该在as 转换期间使用? 以避免崩溃,尽管您不会得到任何单元格!

另外提醒一下,你应该始终使用大写的类名,ProfTableViewCell 而不是profTableViewCell,这是一种很好的做法。

更多信息请参见 ios 天才 Rob Mayoff 的最佳答案:Assertion failure in dequeueReusableCellWithIdentifier:forIndexPath:

【讨论】:

感谢您的及时回复。我认为问题出在那条线上。我在情节提要上使用了具有正确重用标识符的原型单元。但是,一旦我回到我的电脑,我也会尝试这种方法,看看它是否适用于我的情况并发布更新 如果您在情节提要中使用原型单元格,则不应在代码中注册类。【参考方案3】:

您必须创建一个简单的 NSObject 类,其中包含图像、用户名和 userbio 作为可选值。然后你必须在你的 profileviewcontroller 中声明一个像这样的变量:

var allProfiles = [yourNSObjectClass]()

在你的 cellForRowAtIndexPath 添加:

let profile = yourNSObjectClass()
profile = allProfiles[indexPath.row]

cell.username.text = profile.username

然后继续。

也使用这个:

   dispatch_async(dispatch_get_main_queue(), 
                self.tableView.reloadData()
            )

而不是这个:

self.tableView.reloadData()

【讨论】:

有趣...可能! findObjectsInBackgroundWithBlock 是否总是在自己的后台线程上运行? 在我的小经验中是的。这是解决此类问题的好方法。 我之前尝试过这个修复,但仍然遇到同样的错误。如果注册类仍然无法正确编译,将再试一次

以上是关于加载 tableView 时打开可选值时意外发现 nil的主要内容,如果未能解决你的问题,请参考以下文章

在 SWIFT 3.0 中展开可选值时意外发现 nil

在展开可选值时迅速并意外发现 nil

NSFetchedResultsController - 在展开可选值时意外发现 nil

在读取 JSON 时打开可选值时意外发现 nil [关闭]

插座已连接,但在展开可选值时意外发现 nil

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