为啥我在使用该值时得到一个 nil 值,但当我打印它时它显示为 none nil?

Posted

技术标签:

【中文标题】为啥我在使用该值时得到一个 nil 值,但当我打印它时它显示为 none nil?【英文标题】:Why am I getting a nil value when I go to use the value but when I print it it shows up as none nil?为什么我在使用该值时得到一个 nil 值,但当我打印它时它显示为 none nil? 【发布时间】:2019-12-17 18:09:24 【问题描述】:

我正在尝试填充集合视图。当我在字典中使用一个值时,它显示为 nil,但是当我打印它时,它会在它为我提供字符串之前的行。

我之前修复了这个问题,但是当我重新制作我的收藏视图以解决我遇到的另一个错误时,这个错误又回来了。为了解决这个问题,我刚刚删除了 self.users.removeAll() 行。重新添加该行然后删除它这次不起作用。

我在这个函数中遇到了问题:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

    let cell = collectionview.dequeueReusableCell(withReuseIdentifier: "userCell", for: indexPath) as! UserCell

    print(user[indexPath.row].imagePath!)

    cell.userImage.sd_setImage(with: URL(string: user[indexPath.row].imagePath!))

    cell.nameLabel.text = user[indexPath.row].username
    cell.userID = user[indexPath.row].userID

    return cell

这里是完整的代码:

import UIKit
import Firebase
import SwiftKeychainWrapper
import SwiftUI
import FirebaseUI

class UserViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource 

    @IBOutlet weak var collectionview: UICollectionView!

    var user = [User]()

    override func viewDidLoad() 
        super.viewDidLoad()
        collectionview.delegate = self
        collectionview.dataSource = self

        retrieveUsers()
    

    func retrieveUsers() 
       let ref = Database.database().reference()
       ref.child("users/").observeSingleEvent(of:.value, with:  (snapshot) in
          let users = snapshot.value as! [String : NSDictionary]
          //self.user.removeAll()
          for (_, value) in users 
             if let uid = value["uid"] as? String 
                if uid != Auth.auth().currentUser!.uid 
                   let userToShow = User()
                   if let username = value["username"] as? String, let imagePath = value["urlToImage"] as? String 
                      userToShow.username = username
                      userToShow.imagePath = imagePath
                      userToShow.userID = uid
                      self.user.append(userToShow)
                      print(userToShow)
                   
                
             
          

          self.collectionview.reloadData()
       )

       ref.removeAllObservers()
    

    func numberOfSections(in collectionView: UICollectionView) -> Int 
        return 1
    

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell = collectionview.dequeueReusableCell(withReuseIdentifier: "userCell", for: indexPath) as! UserCell

        print(user[indexPath.row].imagePath!)

        cell.userImage.sd_setImage(with: URL(string: user[indexPath.row].imagePath!))
        cell.nameLabel.text = user[indexPath.row].username
        cell.userID = user[indexPath.row].userID

        return cell
    

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return user.count //?? 0
    

    func checkFollowing(indexPath: IndexPath) 
       let uid = Auth.auth().currentUser!.uid
       let ref = Database.database().reference()

       ref.child("users").child(uid).child("following").queryOrderedByKey().observeSingleEvent(of: .value, with:  snapshot in
           if let following = snapshot.value as? [String : AnyObject] 
              for (_, value) in following 
                 if value as! String == self.user[indexPath.row].userID 
//                  self.tableview.cellForRow(at: indexPath)?.accessoryType = .checkmark
                 
              
           
       )

       ref.removeAllObservers()

    

    @IBAction func logOutPressed(_ sender: Any) 
        KeychainWrapper.standard.removeObject(forKey:"uid")

        do 
            try Auth.auth().signOut()
         catch let signOutError as NSError
            print("Error signing out: %@", signOutError)
        
        dismiss(animated: true, completion: nil)
    



extension UIImageView 
    func downloadImage(from imgURL: String!) 
        let url = URLRequest(url: URL(string: imgURL)!)

        let task = URLSession.shared.dataTask(with: url)   (data, response, error) in
            if error != nil 
                print(error!)
                return
            

            DispatchQueue.main.async 
                self.image = UIImage(data: data!)
            
        

        task.resume()
    

我没有正确填充字典吗?

另外,这里是 User 类:

import UIKit

class User: NSObject 
    var userID: String?
    var username: String?
    var imagePath: String?

另外,这是用户字典在调试器中显示的内容:

【问题讨论】:

什么是sd_setImage?如果它是异步的,那就是问题所在。你的代码没有按照你想象的顺序运行。 sd_setImage 是设置 ImageView 的函数。为什么 print 语句会打印一些东西,但紧随其后的行不起作用?异步真的那么不稳定吗?在我重新制作 collectionView 之前,同样的代码正在工作,所以我认为这是另外一回事,但我对 Xcode 太陌生,无法理解 因为后面的行并不是真正的后面。这就是异步的意思。 有没有办法确保该行在之后执行?据我了解,在我调用 reloadData() 之前,不应该格式化集合视图。在用户字典中的条目完成之前,我不会调用 reloadData()。如何确保在所有数据都存在之前不会形成单元格? Nick,请学习了解异步数据处理的工作原理。请接受一些建议,例如在主线程上重新加载集合视图并使用非可选属性和初始化程序声明 User。如果他们对您有帮助,请考虑投票并接受答案。 【参考方案1】:

如果您遇到此错误,请重新连接到您的集合视图单元

【讨论】:

以上是关于为啥我在使用该值时得到一个 nil 值,但当我打印它时它显示为 none nil?的主要内容,如果未能解决你的问题,请参考以下文章

Swift 在尝试从存在的键中获取值时得到 Nil [关闭]

Swift 在尝试获取价值时得到 Nil

为啥尽管我在变量中使用 malloc 分配更多内存,但当我打印变量的大小时,它仍然显示更少的内存/字节? [复制]

为啥 nameof() 在 Linq 表达式中给出一个模棱两可的调用警告,但当我使用与字符串相同的值时却没有?

当我使用 javascript 在 html 中获取 p-tag 的值时,我尝试向该值添加一个特定的数字,但输出给出 NaN

value 不是 nil,而是在展开 Optional 值时意外发现 nil