为啥 if != nil 有时仅在使用应用程序期间有效?

Posted

技术标签:

【中文标题】为啥 if != nil 有时仅在使用应用程序期间有效?【英文标题】:Why the if != nil works only sometimes during the app being used?为什么 if != nil 有时仅在使用应用程序期间有效? 【发布时间】:2020-12-23 23:22:25 【问题描述】:

我遇到了一个问题,需要您的帮助。我正在开发一个应用程序来管理事件,当应用程序加载时,所有帖子都会按预期显示,无论是否有图像进入帖子。如果我添加一个包含图像的新帖子,它会正确保存并返回到显示新帖子的滚动视图,如果我编辑任何有图像的项目并在保存时保留图像或将图像添加到没有图像的帖子中在编辑之前它保存得很好,并且帖子立即显示到滚动视图中。 问题是,如果我尝试创建没有图像的新帖子,或者如果我编辑删除图像并保存的帖子,应用程序由于展开选项而崩溃,但奇怪的是我正在将 nil 值检查到滚动视图的位置显示图像。

ScrollView 
            VStack(spacing: 15)
                ForEach(items, id: \.self)  item in
                    VStack(spacing: 15) 
                        if item.pic != nil 
                            
                            ZStack(alignment: Alignment(horizontal: .trailing, vertical: .top)) 
                                
                                Image(uiImage: UIImage(data: item.pic!)!)
                                    .resizable()
                                    .aspectRatio(contentMode: .fill)
                                    .cornerRadius(15)
                            
                            .padding()
                            .opacity(1)
                        

有什么想法吗?非常感谢您的支持。

【问题讨论】:

【参考方案1】:

这里有两个强制解包。您对!= nil 的测试仅保护第一个;访问item.pic 数据的尝试。但是,如果将该数据转换为UIImage 失败怎么办? - 可失败的初始化程序将返回 nil,然后您强制解包 - 这将导致崩溃。

更安全的方法是避免所有强制展开。我会在你的模型中添加一个计算属性:

extension Item 
    var image: Image? 
        guard let data = self.pic, let uiImage = UIImage(data: data) else 
            return nil
        
        return Image(uiImage: uiImage)
    

那么你可以说:

ScrollView 
    VStack(spacing: 15)
        ForEach(items, id: \.self)  item in
            VStack(spacing: 15) 
            if let image = item.image 
                ZStack(alignment: Alignment(horizontal: .trailing, vertical: .top)) 
                    image
                     .resizable()
                     .aspectRatio(contentMode: .fill)
                     .cornerRadius(15)
                 
                  .padding()
                  .opacity(1)
                
            
        
    

您还可以将整个 ZStack 封装在 View 子类中以进一步简化事情

您可以返回占位符图像,而不是返回可选的Image;这取决于你。

【讨论】:

Paulw11,你摇滚!完美,经过你的解释看起来很容易。非常感谢。

以上是关于为啥 if != nil 有时仅在使用应用程序期间有效?的主要内容,如果未能解决你的问题,请参考以下文章

为啥有时会立即释放内存,而有时仅在自动释放池耗尽时才释放内存?

为啥在释放对象后使用'nil'

为啥线程在进程间通信期间会破坏命名管道?

为啥将 [super init] 放在 if 语句中,因为无论返回是不是为 nil,我们还是返回它?

NSEntityDescription 仅在 iPad Air 7.1 上返回 nil

为啥在 bash if 语句中未设置的变量被评估为 0