每次我尝试访问它时,结构的 UUID 类型的 id 都会发生变化[重复]

Posted

技术标签:

【中文标题】每次我尝试访问它时,结构的 UUID 类型的 id 都会发生变化[重复]【英文标题】:Struct's id of type UUID changes everytime i try to access it [duplicate] 【发布时间】:2021-10-15 17:30:18 【问题描述】:

我有一个从 JSON 解析的结构,但包含另一个必须可识别的结构 Article。它看起来像这样:

import Foundation

struct TopHeadlines: Codable 
    var totalArticles: Int
    var articles: [Article]

    struct Article: Codable 
        var title: String
        var description: String
        var url: String
        var image: String
        var publishedAt: String
        var source: Source
    
    
    struct Source: Codable 
        var name: String
        var url: String
    
    
    var json: Data? 
        return try? JSONEncoder().encode(self)
    



extension TopHeadlines.Article: Identifiable 
    var id: UUID  return UUID() 

我需要生成 UUID 来访问 newImages 字典中的图像:

List(viewModel.articles, id: \.id)  article in
                    HStack 
                        OptionalImage(uiImage: viewModel.newsImages[article.id])
                        Text(article.id.uuidString)
                        Text(article.id.uuidString)
                        Text(article.id.uuidString)

                    
                

但是三个文本视图会打印三个不同的 UUID:

CC83B8AE-61B1-4A7D-A8A4-1B1E98C27CE7
545C1D28-F098-48A3-8C3C-A98BB54F9751
39B8383C-A2D8-46B0-BA51-1B861AF09762

我应该如何为Article struct 创建 ID,这样它就不会每次都重新生成?

【问题讨论】:

那个id属性是一个计算属性,所以每次访问它都会返回一个全新的UUID。 【参考方案1】:

您的扩展中的id 属性是一个计算属性,因此每次调用都会生成一个新的 UUID (UUID())。

由于您不能在扩展中存储属性,请尝试将其直接添加到 Article 结构中,如下所示:

struct Article: Codable, Identifiable 
    var id = UUID()
    var title: String
    var description: String
    var url: String
    var image: String
    var publishedAt: String
    var source: Source

这只会在结构初始化时生成一个 UUID。

【讨论】:

【参考方案2】:

您已将id 声明为计算属性,因此根据定义,每次访问该属性时都会返回一个新的UUID 实例。

您需要将该属性设置为存储的不可变属性,以确保UUID 永远不会更改。

您还需要手动声明一个符合CodingKeyenum 并在其大小写中省略id 键,以告诉编译器不应从JSON 中解码id

struct TopHeadlines: Codable 
    var totalArticles: Int
    var articles: [Article]

    struct Article: Codable, Identifiable 
        var title: String
        var description: String
        var url: String
        var image: String
        var publishedAt: String
        var source: Source

        let id = UUID()

        private enum CodingKeys: String, CodingKey 
            case title, description, url, image, publishedAt, source
        
    

    struct Source: Codable 
        var name: String
        var url: String
    

    var json: Data? 
        return try? JSONEncoder().encode(self)
    

【讨论】:

【参考方案3】:

扩展不能存储属性,这就是为什么您将id 实现为计算属性,并且每个新的UUID() 都是唯一的

最明显的解决方案是将它移动到你的结构中

struct Article: Codable 
    let uuid = UUID()
    // ...

这样声明它在解码或创建新对象时都不需要值。


但是如果你不能编辑这个结构(这可能是你使用扩展的原因),你可以做以下事情:用Hashable扩展你的结构,然后你可以访问对象hashValue,这是计算出来的基于所有属性,因此该值仅对于所有属性中具有相同值的两个对象是相同的,这通常适合唯一标识符

extension Article: Hashable 
    

用法

Text("\(article.hashValue)")

【讨论】:

以上是关于每次我尝试访问它时,结构的 UUID 类型的 id 都会发生变化[重复]的主要内容,如果未能解决你的问题,请参考以下文章

为啥在尝试使用指针访问结构时出现此分段错误?

休眠 UUID 为 UUID 类型

我可以将 SORM id 类型更改为 UUID 吗?

多态关联Rails:不同的primary_keys类型(id&uuid)

c++ 创建一个不是 UUID 类型的全局唯一 id

带有 UUID 主键的 ActiveRecord 迁移