【问题标题】:Safe unwrapping of optionals in foreach loop not allowing app to build在 foreach 循环中安全展开选项不允许应用程序构建
【发布时间】:2022-01-08 13:08:45
【问题描述】:

我有一本字典 postsAuthorsProfilePicturesURLs[String: URL],其中存储了 post ID 以及帖子作者个人资料图片的相应 URL。我最初在 ViewModel 中初始化它:

@Published var postsAuthorsProfilePicturesURLs: [String: URL] = [:] 

Posts IDs 是从 ViewModel 中的 firebase 获取的。出于测试目的,对于每个 post id key,我在 ViewModel 中以相同方法为某些图像分配相同的 valid url 值。 问题出在视图本身。在 ForEach 循环中,我试图显示帖子及其详细信息,以及帖子作者的 profilePictures。为此,我使用AsyncImage

我有以下代码:

AsyncImage(url: homeViewModel.postsAuthorsProfilePicturesURLs[post.id]!) { phase in
    if let image = phase.image {
        image
            .resizable()
            .aspectRatio(contentMode: .fit)
            .clipShape(RoundedRectangle(cornerRadius: 50))
            .frame(width: screenWidth * 0.15, height: screenHeight * 0.15)
    } else {
        Image(uiImage: UIImage(named: "blank-profile-hi")!)
            .resizable()
            .aspectRatio(contentMode: .fit)
            .clipShape(RoundedRectangle(cornerRadius: 50))
            .frame(width: screenWidth * 0.15, height: screenHeight * 0.15)
    }
}

它可以正确渲染从 url 下载的异步图像。但是,我想以更安全的方式打开可选的homeViewModel.postsAuthorsProfilePicturesURLs[post.id]。比如这样:

if let profilePictureURL = homeViewModel.postsAuthorsProfilePicturesURLs[post.id] {
    AsyncImage(url: profilePictureURL) { phase in
        if let image = phase.image {
            image
                .resizable()
                .aspectRatio(contentMode: .fit)
                .clipShape(RoundedRectangle(cornerRadius: 50))
                .frame(width: screenWidth * 0.15, height: screenHeight * 0.15)
        } else {
            Image(uiImage: UIImage(named: "blank-profile-hi")!)
                .resizable()
                .aspectRatio(contentMode: .fit)
                .clipShape(RoundedRectangle(cornerRadius: 50))
                .frame(width: screenWidth * 0.15, height: screenHeight * 0.15)
        }
    }
}

虽然此更改不允许应用构建。使用 nil 检查时也存在同样的问题:

if homeViewModel.postsAuthorsProfilePicturesURLs[post.id] != nil

我不知道如何处理。

编辑:

实际上,我尝试通过注释整个视图的部分来将表达式分解为不同的子表达式,结果发现带有 AsyncImage 的部分是完全正确的。不正确的是我附加到此视图不同部分的 .confirmationDialog 部分。现在由于这个确认对话框,应用程序将无法编译

.confirmationDialog("What", isPresented: $showPostOptions) {
    Button("Edit") {
        sheetManager.postID = post.id
        sheetManager.postText = post.text
        sheetManager.whichSheet = .editView
        sheetManager.showSheet.toggle()
    }
    
    Button("Delete", role: .destructive) {
        self.homeViewModel.deletePost(postID: post.id)
    }
}

使用AsyncImage.confirmationDialog 注释代码部分可以构建应用。

【问题讨论】:

  • 错误信息是什么?
  • 没有有用的错误信息:The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions
  • 其实我试过breaking up the expression into distinct sub-expressions,通过评论整个View的部分,结果发现AsyncImage部分是完全正确的。不正确的是带有.confirmationDialog 的部分,我已将其附加到此视图的不同部分。现在应用程序不会因为这个confirmationDialog而编译

标签: ios swift foreach swiftui optional


【解决方案1】:

我设法通过将问题所在的一个视图拆分为 3 个较小的子视图来解决问题,这些子视图在主视图中连接。所以看起来 .confirmationDialog 修饰符和可选的展开都是正确的。我之前的观点一定是太大了。

【讨论】:

    猜你喜欢
    • 2012-05-14
    • 2012-11-23
    • 2018-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    • 2017-02-11
    相关资源
    最近更新 更多