链接到用户的属性默认导致应用崩溃

时间:2016-12-06 18:01:03

标签: ios swift

我的初始视图控制器中的属性是否在调用AppDelegate函数didFinishLaunchingWithOptions之前或之后设置?

以下是AppDelegate中的代码。当我的应用程序首次启动时,如果用户默认为" CurrentDateBool"尚未设置,它设置为true。

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    if UserDefaults.standard.value(forKey: "currentDateBool") == nil {
      UserDefaults.standard.setValue(true, forKey: "currentDateBool")
    }
    return true
}

这是我的初始视图控制器。这会在currentDateBool属性上崩溃我的应用程序,因为它是零。但是,它不应该是nil,因为它在AppDelegate中将其设置为true。我认为AppDelegate在初始视图控制器之前设置。有人可以澄清属性设置的顺序吗?

class TimestampTableViewController: UITableViewController {

  var currentDateBool = UserDefaults.standard.value(forKey: "currentDateBool") as! Bool

  override func viewDidLoad() {
    super.viewDidLoad()  
  }
 ...
}

如果我在viewDidLoad中将currentDateBool属性设置为用户默认值,我可以使用它。

class TimestampTableViewController: UITableViewController {

  var currentDateBool = true

  override func viewDidLoad() {
    super.viewDidLoad()  
    currentDateBool = UserDefaults.standard.value(forKey: "currentDateBool") as! Bool
  }
 ...
}

1 个答案:

答案 0 :(得分:0)

  

如果我将currentDateBool属性设置为viewDidLoad

中的用户默认值,我可以使其正常工作

确实如此。这正是你应该做的。

您正在使用主要故事板。这意味着您的初始界面是从故事板加载的,之前运行didFinishLaunchingWithOptions中的代码。因此,虽然TimestampTableViewController还没有视图,但存在 - 意味着它已经被实例化,因此它的属性已被赋予其初始值。

要看到这是真的,只需制作一个基本的香草项目,如下所示:

// in the app delegate

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    print("one")
    return true
}

// in the main view controller

class ViewController: UIViewController {
    let what : Void = {print("two")}()
}

您将在控制台中看到two,然后是one

但如果您将what移至viewDidLoad,您会看到one,然后是two。这是因为在这种情况下,视图控制器的视图之后在代理程序代理中运行时才会加载。