每次我尝试访问它时,UUID 类型的结构 ID 都会更改
Struct's id of type UUID changes everytime i try to access it
我有一个从 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
结构创建 ID 以便它不会每次都重新生成?
您的扩展程序中的 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。
您已将 id
声明为计算 属性,因此根据定义,每次访问 属性 时都会返回一个新的 UUID
实例。
您需要将 属性 设为存储的不可变 属性 以确保 UUID
永不更改。
您还需要手动声明一个 CodingKey
符合 enum
并从其案例中省略 id
键,以告诉编译器 id
不应从中解码JSON.
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)
}
}
扩展无法存储属性,这就是为什么您将 id
实现为计算 属性,并且每个新的 UUID()
都是唯一的
最明显的解决方案是将其移动到您的结构中
struct Article: Codable {
let uuid = UUID()
// ...
}
像这样声明它在解码或创建新对象时都不需要值。
但是如果您不能编辑此结构(这可能是您使用扩展的原因),您可以执行以下操作:使用 Hashable
扩展您的结构,然后您可以访问对象 hashValue
是基于所有属性计算的,所以只有在所有属性中具有相同值的两个对象,这个值才会相同,这通常适合唯一标识符
extension Article: Hashable {
}
用法
Text("\(article.hashValue)")
我有一个从 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
结构创建 ID 以便它不会每次都重新生成?
您的扩展程序中的 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。
您已将 id
声明为计算 属性,因此根据定义,每次访问 属性 时都会返回一个新的 UUID
实例。
您需要将 属性 设为存储的不可变 属性 以确保 UUID
永不更改。
您还需要手动声明一个 CodingKey
符合 enum
并从其案例中省略 id
键,以告诉编译器 id
不应从中解码JSON.
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)
}
}
扩展无法存储属性,这就是为什么您将 id
实现为计算 属性,并且每个新的 UUID()
都是唯一的
最明显的解决方案是将其移动到您的结构中
struct Article: Codable {
let uuid = UUID()
// ...
}
像这样声明它在解码或创建新对象时都不需要值。
但是如果您不能编辑此结构(这可能是您使用扩展的原因),您可以执行以下操作:使用 Hashable
扩展您的结构,然后您可以访问对象 hashValue
是基于所有属性计算的,所以只有在所有属性中具有相同值的两个对象,这个值才会相同,这通常适合唯一标识符
extension Article: Hashable {
}
用法
Text("\(article.hashValue)")