gpt4 book ai didi

ios - 从结构模型填充 View 时的 nil 值

转载 作者:行者123 更新时间:2023-11-28 07:15:39 27 4
gpt4 key购买 nike

我在用数据填充 View 时遇到问题。我创建了一个名为 WeatherData.swift 的结构,它保存我从一些已解析的 JSON 中获取的属性。

struct WeatherData {

var currentTemp: Int?


init( city: NSString) {

//grab some JSON via NSURLSession & SwiftyJSON and assign in a closure

self.currentTemp = json["currently"]["temperature"].int

println("heres the current temp: \(self.currentTemp!)")

//heres the current temp: 65
}

}

很酷,打印效果很好!但是当我试图为 UILabel 赋值时在 View Controller 上:

func requestDataForCity() {

currentLocationData = WeatherData(city: savedCity)

var label = UILabel()
label.frame = CGRectMake(0, 0, 40, 40)
label.backgroundColor = UIColor.yellowColor()
label.text = "\(currentLocationData.currentTemp!)"

scrollView.addSubview(label)
}

我得到 currentLocationData.currentTemp 为 nil。我想也许我的代码在初始化之前将 currentTemp 属性分配给标签,所以我使用了 NSNotifcationCenter,但这也没有用。关于我做错了什么的任何想法?

https://github.com/yamski/weatherApp

最佳答案

您的问题似乎是您在 init 完成后在闭包中分配值。您没有在代码中显示闭包,但我认为它看起来像这样:

struct WeatherData {
var currentTemp: Int?
init( city: NSString) {
let request = NSURLRequest(URL: NSURL(string: "http://site/data"))
NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
self.currentTemp = readTheData(data)
println("heres the current temp: \(self.currentTemp!)")
}).resume()
}
}

如果将 currentTempvar 更改为 let,您将在赋值时遇到错误:无法赋值 ' “ self ”中的 currentTemp。这将确认您正在尝试在 init 完成后分配值。同样,如果您将 println 移出闭包,您会在尝试打印 nil 时看到应用程序崩溃。

如果您正在寻找同步 API,您可以做的一件事是阻止执行直到完成:

struct WeatherData {
var currentTemp: Int?
init( city: NSString) {
var semaphore = dispatch_semaphore_create(0)
let request = NSURLRequest(URL: NSURL(string: "http://site/data"))
NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
self.currentTemp = readTheData(data)
dispatch_semaphore_signal(semaphore)
}).resume()
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
}
}

虽然这种方法有问题:

  • 这当然会在您每次在主队列上初始化 WeatherData 时停止您的 UI。
  • 它假定 NSURLSession 有一个与当前正在运行的队列不同的 delegateQueue。否则会陷入僵局。
  • 我还没有看到文档明确说明 init 中的变异操作一定会影响当前实例。 Swift 在闭包中有一个完全不同的 self 副本是合理的。

更好的方法是将工作移出结构,其签名如下所示,其中 completionHandler 在主队列中被调用:

func getWeatherForCity(city:NSString, completionHandler: ((WeatherData) -> Void)?)

WeatherData 会有一个初始化函数,它只需要 JSON 数据来提取温度:

struct WeatherData {
let currentTemp: Int
init(json:JSON) {
currentTemp = json["currently"]["temperature"].int
}
}

那么您的 UI 代码可能如下所示:

func requestDataForCity() {
getWeatherForCity(savedCity, completionHandler: { weather -> Void in
currentLocationData = weather

var label = UILabel()
label.frame = CGRectMake(0, 0, 40, 40)
label.backgroundColor = UIColor.yellowColor()
label.text = "\(currentLocationData.currentTemp!)"
scrollView.addSubview(label)
})
}

关于ios - 从结构模型填充 View 时的 nil 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26389867/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com