简体   繁体   English

未包装可选类型EKReminder的值

[英]Value of optional type EKReminder not unwrapped

I am trying to create reminder according to this tutorial, trying to change the Swift 1 to Swift 2 code: 我正在尝试根据本教程创建提醒,尝试将Swift 1更改为Swift 2代码:

http://www.techotopia.com/index.php/Using_iOS_8_Event_Kit_and_Swift_to_Create_Date_and_Location_Based_Reminders http://www.techotopia.com/index.php/Using_iOS_8_Event_Kit_and_Swift_to_Create_Date_and_Location_Based_Reminders

I get the error: Value for optional type not unwrapped. 我收到错误消息: 未包装可选类型的值。

func createReminder() {

    if (appDelegate!.eventStore != nil) {
        let reminder = EKReminder(eventStore: appDelegate!.eventStore) //value not unwrapped

        reminder.title = reminderText.text
        reminder.calendar =
            appDelegate!.eventStore!.defaultCalendarForNewReminders()
        let date = myDatePicker.date
        let alarm = EKAlarm(absoluteDate: date)

        reminder.addAlarm(alarm)

        var error: NSError?
        appDelegate!.eventStore!.saveReminder(reminder,
            commit: true, error: &error)

        if error != nil {
            print("Reminder failed with error \(error?.localizedDescription)")
        }
    }
}

I understand the concept of optional value (variable can be not assigned a value at this point during run time), what I do not understand is that I am inside the if block, that checks the value for not being nil. 我了解可选值的概念(在运行时此时不能为变量赋值),我不明白的是我在if块中,该块检查该值是否为nil。 Therefore appDelegate!.eventStore is not nil in this block, therefore does not need to be unwrapped (?). 因此appDelegate!.eventStore在此块中不为nil,因此不需要解包(?)。 I also tried setting the "!" 我也尝试设置“!” after this variable, like this: 在此变量之后,如下所示:

appDelegate!.eventStore!

but it breaks other code, it gives error around this code: 但它破坏了其他代码,因此在此代码周围出现错误:

appDelegate!.eventStore!.saveReminder(reminder,
            commit: true, error: &error)  //extra argumenr 'error' in call 

Surrounding it with do{}catch{} statement does not help.. 用do {} catch {}语句将其括起来无济于事。

By the looks of it, this is more to do with the extra argument than with the implicitly unwrapped optional — Apple have updated a lot of their SDK for Swift 2, to avoid passing in the reference to the NSError object and use try instead. 从外观上看,这更多地是与多余的参数有关,而不是与隐式解包的可选内容有关— Apple已为Swift 2更新了许多SDK,以避免传递对NSError对象的引用,而改用try

eventStore.saveReminder(reminder, commit: true, error: &error)

becomes 变成

do {
    try eventStore.saveReminder(reminder, commit: true)
}
catch error: NSError {
    print(error.localizedDescription)
}

As a general rule, I avoid implicitly unwrapped optionals like the plague — there is very little need for them and when they do exist you can always make a proper non-optional. 作为一般规则,我避免像瘟疫那样隐式地解开可选的选项—几乎不需要它们,当它们确实存在时,您始终可以制作适当的非可选项。 Try: 尝试:

func createReminder() throws {

    guard let eventStore = appDelegate?.eventStore else {
        let error: NSError = NSError(domain: "com.mycompany.myapp", code: 1, userInfo: [
        NSLocalizedDescriptionKey: "Unable to get event store from app delegate"
        ])
        throw error
    }

    let reminder = EKReminder(eventStore: eventStore)

    reminder.title = reminderText.text
    reminder.calendar = eventStore.defaultCalendarForNewReminders()
    let date = myDatePicker.date
    let alarm = EKAlarm(absoluteDate: date)

    reminder.addAlarm(alarm)

    try eventStore.saveReminder(reminder, commit: true)
}

That way you are not playing around with implicitly unwrapped optionals, eventStore is guaranteed to be set when you use it and whatever calls createReminder() can handle the error is there is one (you would probably also throw an error instead of printing out if the eventStore is not set). 这样一来,您就不会再使用隐式解包的可选eventStore可以确保在使用它时设置eventStore ,无论调用createReminder()可以处理该错误是什么,如果存在错误(您可能还会抛出一个错误而不是打印出来)未设置eventStore )。

Ok, I am not sure about the code, but I fixed the errors, I needed to still use the do-try-catch, but like so: 好的,我不确定代码,但是我修复了错误,我仍然需要使用do-try-catch,但是就像这样:

     do {
            try appDelegate!.eventStore!.saveReminder(reminder, commit: true) 
        } catch {
            print(error)
        }

if you check an optional value for nil 如果检查nil的可选值

if (appDelegate!.eventStore != nil) {

you have to unwrap it in case it's not nil 你必须解开它的情况下,它不是nil

let reminder = EKReminder(eventStore: appDelegate!.eventStore!)

A more suitable way is to use optional bindings 一种更合适的方法是使用可选绑定

if let store = appDelegate!.eventStore {
 let reminder = EKReminder(eventStore: store)
  …
}

What is the purpose to declare appDelegate as optional? appDelegate声明为可选的目的是什么?
The AppDelegate class exists in any application by default and could be never nil . 默认情况下, AppDelegate类存在于任何应用程序中,并且永远不会为nil

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM