【问题标题】:Data immediately deallocated数据立即解除分配
【发布时间】:2020-02-27 22:32:06
【问题描述】:

我目前正在为我的应用程序开发一个标题 UI 元素,我遇到了我的数据被立即释放的问题。我一直试图让控制台打印它接收到的任何数据,但我什至在控制台中都没有看到。我想要实现的是让应用程序连接到其目标“CDN”,然后为头条新闻提取数据。使用 PHP 我正在执行一个 SQL 查询来生成一个数组,然后应用程序将使用该数组。运行所述脚本时,会生成以下数组。

{"id":"1","title":"Meet ergoWare","header_image":"https://gba.ergoware.io/cache/content/topstory/ergo_news_01.svg","summary":"GBA's New Ergonomic Portal!"}

令人惊叹的数组是的,所以下一部分将在应用程序中读取和编译以创建标题卡片,但问题是我无法加载要加载的数据。我知道我缺少一些东西,但是如果没有编译器将我指向我需要的方向,我就会摸索它。所以这里是 Swift 代码。

import SwiftUI

struct Response: Codable {
    var results: [Article]
}

struct Article: Codable, Identifiable {
    var id: Int
    var title: String
    var header_image: String
    var summary: String
}

struct HeadlineUI: View {
    @State var results = [Article]()
    var CDNLink: String

    var body: some View {
        ScrollView(.horizontal) {

            HStack(spacing: 20) {
                ForEach(results) { result in
                    CardView(image: result.header_image, summary: result.summary, heading: result.title)
                }
                .onAppear(perform: { self.loadData() })
            }
        }
    }

    func loadData() {
        guard let url = URL(string: CDNLink) else {
            print("Invalid URL")
            return
        }
        let request = URLRequest(url: url)

         URLSession.shared.dataTask(with: request) { data, response, error in
            if let data = data {
                if let decodedResponse = try? JSONDecoder().decode(Response.self, from: data) {
                    DispatchQueue.main.async {
                        self.results = decodedResponse.results
                        print(self.results)
                    }
                    return
                }
            }
            print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")")
        }.resume()
    }
}

struct HeadlineUI_Previews: PreviewProvider {
    static var previews: some View {
        HeadlineUI(CDNLink: "https://gba.ergoware.io/cdn?funct=fetchNews")
    }
}

所以应该发生的是它连接到“CDN”并读取数组。然后插入该信息,对于由 id 定义的结果的每个索引,应显示一张卡片,其中包含头条新闻图像、文章标题和简短摘要。我开始对 Swift 感到更自在了,但是像这样的小问题一直在破坏我的信心,哈哈。感谢您提供任何可教的时刻。

【问题讨论】:

  • try? JSONDecoder()改成try! JSONDecoder()会看到错误
  • 另外,您发布的 JSON 是一个对象,而不是一个数组,而您的 Swift 代码期望的是一个具有属性 results 的对象
  • @zaitsman 条件绑定的初始化程序必须具有可选类型,而不是“响应”是我得到的错误。
  • 嗯,是的,这很明显,如果您要切换到try!,则还必须删除您的if let ={},只需删除if 语句后的if{}
  • 修改代码如下:``` if let data = data { let decodedResponse = try! JSONDecoder().decode(Response.self, from: data) DispatchQueue.main.async { self.results = decodedResponse.results print(self.results) } } ``

标签: json swift swiftui


【解决方案1】:

我找到了,请按以下步骤操作:

  1. 根据你的类 Response,你的服务应该返回这个 JSON:

    {
    "results" : [{
       "id":1,
       "title":"Meet ergoWare",
       "header_image":"https://gba.ergoware.io/cache/content/topstory/ergo_news_01.svg",
       "summary":"GBA's New Ergonomic Portal!"
    }]
    }
    

    尝试使用这个url

  2. 您应该将 .onAppear 放在 HStack 中,而不是放在 ForEach 中。这是一个完整的例子:

    struct Response: Codable {
        var results: [Article]
    }
    
    struct Article: Codable, Identifiable {
        var id: Int
        var title: String
        var header_image: String
        var summary: String
    }
    
    struct HeadlineUI: View {
    @State var results = [Article]()
    var CDNLink: String
    
    var body: some View {
        ScrollView(.horizontal) {
            HStack(spacing: 20) {
                Text("Response:")
                ForEach(results) { result in
                    Text(result.title)
                }
    
            }.onAppear(perform: { self.loadData() })
        }
    }
    
    func loadData() {
        guard let url = URL(string: CDNLink) else {
            print("Invalid URL")
            return
        }
        let request = URLRequest(url: url)
    
        URLSession.shared.dataTask(with: request) { data, response, error in
            if error != nil {
                print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")")
                return
            } else {
                do {
                    let decodedResponse = try JSONDecoder().decode(Response.self, from: data!)
                    print(decodedResponse)
                    self.results = decodedResponse.results
                } catch let err {
                    print("Error parsing: \(err)")
    
                }
            }
        }.resume()
    }
    }
    

【讨论】:

  • 所以我尝试编译它,但我仍然没有在 UI 或控制台中得到任何结果。
  • 您能在日志中看到错误吗?您的服务是否返回了正确的 JSON?尝试使用此网址:mocky.io/v2/5e585d202f00000205961ec9
  • 我不能,我的问题是我的控制台日志中没有出现任何错误。
  • 这段代码非常适合我,尝试重新连接设备以重新启动控制台,并确保您的服务返回您的代码所期望的 JSON,否则 JSONDecoder() 将失败
  • 会做,会报告回来
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-17
  • 1970-01-01
  • 2020-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-26
相关资源
最近更新 更多