【问题标题】:In SwiftUI,how to "Foreach" nodes in a LinkedList?在 SwiftUI 中,如何在 LinkedList 中“Foreach”节点?
【发布时间】:2021-10-20 08:56:50
【问题描述】:

我尝试在 SwiftUI 中使用 Foreach 中的 LinkedList,但遇到了一些问题。以下代码可以在 Playground 中运行(Foreach),但在 SwiftUI 中不起作用。我想通过 CORE(即节点)绘制我的 UI,所以我必须使它与 Foreach 一起工作。我知道这与可哈希协议有关,但我不知道该怎么做。

import Foundation

struct CPU:Sequence{
    public var head:Core?
    

    func makeIterator() -> CPUCoreIterator { 
        return CPUCoreIterator(self)
    }
    mutating func insert(tmp:Float,clocks:Float,load:Float,_ i:Int){
        if head == nil && i == 0 {
            head = Core(tmp, clocks,load,id: i)
            return
        }
        var count:Int = 0
        var current = head
        while(current?.nextCore != nil && count<i){
            current = current?.nextCore
            count+=1
        }
        //add core to the CpuCoreList
        if current?.nextCore == nil && count<i {
            current?.nextCore = Core(tmp,clocks,load,id: i)
            return
        }
        //change the core
        if current != nil {
            current?.load = load
            current?.clocks = clocks
            current?.tmp = tmp
            return
        }
        
    }
    func listAll(){
        if head == nil {
            print("No item")
            return
        }
      var current = head
        while(current != nil){
            print(current!.tmp)
            current = current?.nextCore
        }
    }
    
}
class Core:Identifiable {
    public var id:Int
    public var tmp:Float
    public var clocks:Float
    public var load:Float
    public var nextCore:Core?
    
    init(_ tmp:Float,_ clocks:Float,_ load:Float,id:Int){
        self.clocks = clocks
        self.tmp = tmp
        self.load = load
        self.id = id
        self.nextCore = nil
    }
}

struct CPUCoreIterator:IteratorProtocol {
    let cpucorelist:CPU
    var current:Core?
    init(_ cpucorelist:CPU){
        self.cpucorelist = cpucorelist
        current = cpucorelist.head
    }
    mutating func next() -> Core? {
        defer {
            current = current?.nextCore
        }
        guard current != nil
        else { return nil }
        return current
    }
}

查看代码:

    class Test:ObservableObject {
    @Published var cpu = CPU()
}

struct ContentView: View {
    @ObservedObject var test = Test()
    var body: some View {
        VStack{
            ForEach(test.cpu,id: \.self) { core in
                Text("")
            }
        }
    }
}

【问题讨论】:

  • ForEach 期望数据为 RandomAccessCollection,因此您需要使您的 CPU 符合该协议。
  • 或者用数组替换链表
  • 或者,您可以尝试设置class Core: Identifiable, Hashable, Equatable {...},然后使用ForEach(Array(test.cpu)) {...}

标签: swift foreach swiftui linked-list


【解决方案1】:

制作class Core: Identifiable, Hashable, Equatable 并在ForEach 中使用数组,如图所示,对我来说效果很好。

struct ContentView: View {
    @ObservedObject var test = Test()
    var body: some View {
        VStack{
            ForEach(Array(test.cpu)) { core in   // <--- here
                Text("id: " + String(core.id) + " tmp: " + String(core.tmp))
            }
        }
        .onAppear {
            test.cpu.head = Core(1.1, 2.2, 3.3, id: 1)
            test.cpu.insert(tmp: 9.2, clocks: 8.2, load: 7.2, 2)
            test.cpu.insert(tmp: 5.3, clocks: 4.3, load: 6.3, 3)
        }
    }
}

class Core: Identifiable, Hashable, Equatable {  // <--- here
    public var id:Int
    public var tmp:Float
    public var clocks:Float
    public var load:Float
    public var nextCore:Core?
    
    static func == (lhs: Core, rhs: Core) -> Bool { // <--- here
        lhs.id == rhs.id
    }
    func hash(into hasher: inout Hasher) { // <--- here
        hasher.combine(id)
    }
    
    init(_ tmp:Float,_ clocks:Float,_ load:Float, id:Int){
        self.clocks = clocks
        self.tmp = tmp
        self.load = load
        self.id = id
        self.nextCore = nil
    }
}

【讨论】:

  • 不完全是我想要的,但谢谢>。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多