【问题标题】:Swift: NSUserDefaults not setting straight awaySwift:NSUserDefaults 没有立即设置
【发布时间】:2016-02-29 14:55:35
【问题描述】:

我有什么

我有一个视图控制器 (SelectNameViewController),上面有一个 UITableView 和一个名称列表。当用户点击一个名字时,它会转到一个 ViewController (ResultController),它有一个容器视图,可以加载 3 个 ViewControllers (vc1,vc2, vc3) 允许用户滚动浏览。

ResultController 我有一个连接到 JSON 文件并根据所选名称下载信息的 alamofire 请求:

Alamofire.request(.GET, sendyURLSet, parameters: ["name": passedName, "api_key": api_key])
.responseJSON { response in
    switch response.result {
       case .Success:

       if let value = response.result.value {
          let json = JSON(value)

          self.age = json["age"].stringValue
          self.userInfo.setValue(self.age, forKey: "age")

        }
       case .Failure(let error):
           print(error)
   }
}

VC1 我的 viewDidAppear

中有这个
if let a = userInfo.stringForKey("age") {
        print("Age:  \(a)")
    } else {
        print("nope")
}

问题

在从 Alamofire 请求加载内容后,我无法在 PageViewController 子视图上加载数据。

当用户单击一个名称并被带到 ResultController 时,3 个视图会加载到容器视图中。出现的第一个屏幕是 vc1

但是,在控制台中我只是得到:

没有

如果我滑动到 vc2 然后回到 vc1 我会得到:

32 岁

在控制台中。

问题

谁能告诉我为什么 ViewController (vc1) 的第一个演示文稿中没有显示该值并告诉我如何解决它?

快把我逼疯了

【问题讨论】:

  • 不要使用NSUserDefaults在控制器之间传递数据。使用 segues、协议 - 委托模式或通知(按推荐优先级顺序)
  • 三个视图控制器在加载到容器视图时没有转场。

标签: ios swift uipageviewcontroller alamofire


【解决方案1】:

看起来 vc1 的加载速度比数据提取完成的速度快。

要么等待数据加载完毕再加载新的控制器,要么数据完成后直接设置标签

【讨论】:

    【解决方案2】:

    很可能,对您的Alamofire.request 的回调是在viewDidAppear 之后调用的,这就解释了为什么您看不到您在回调中设置的值。

    你应该想要的是你的代码

    if let a = userInfo.stringForKey("age") { print("Age: \(a)") } else { print("nope") }

    在回调执行后调用。

    你有几种方法:

    • resultsController 调用 VC1 以使其更新其 UI;

    • 从回调中加载resultsController(实际上,您确保在回调中第一次调用它的view方法,即当您将其作为子视图添加到父视图时);

    • 或者,您使用KVO 使VC1 观察对userInfo.age 的任何更改。这种方法需要通过从 NSUserDefaults 派生一个新类来自定义 NSUserDefaults

    【讨论】:

    • 我认为这与请求有关。我如何从 vc1 等待视图(ReportsView)在加载数据之前完成它的业务?
    • 我对此有点小菜鸟,所以非常感谢您的帮助:)
    • 请看我提到的 3 个选项。
    • 好的,所以对于选项 3 (KVO),我是否相信该选项仅适用于 NSObject 类?所以这行不通,对吧?选项 2: resultsController 中有 alamofire 代码,所以可以重新加载视图吗?这不会造成重复循环吗?这留下了选项 1 - 我不确定如何“调用”视图控制器。有什么指点吗?
    • KVO 实际上可以在 Swift 中工作,没有问题 - 但如果您从未使用过 KVO(在 Swift 或 ObjC 中),那么它无疑是最难的选择。至于选项 2,我知道 resultsController 在某些时候会实例化 VC1 并将其添加为子视图。是对的吗?您应该从回调中运行该代码。至于选项3,只需在resultsController 的属性中保留对VC1 的引用,然后在回调中对该引用调用viewDidAppear(或者更好的是,定义一个临时方法,例如updateUI,那会更干净)
    【解决方案3】:

    尝试以下一个。我想它可能会对你有所帮助。

    网络调用完成后(在完成处理程序块中),使用 outlet 为 UI 元素(如标签)设置值。并调用- (void)setNeedsLayout方法。

    该方法表示图层的子图层的布局发生了变化,必须更新。当图层的边界发生变化时,系统通常会自动调用此方法。

    【讨论】:

      猜你喜欢
      • 2019-08-30
      • 2015-10-22
      • 2018-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多