繁体   English   中英

未包装可选类型EKReminder的值

[英]Value of optional type EKReminder not unwrapped

我正在尝试根据本教程创建提醒,尝试将Swift 1更改为Swift 2代码:

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

我收到错误消息: 未包装可选类型的值。

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)")
        }
    }
}

我了解可选值的概念(在运行时此时不能为变量赋值),我不明白的是我在if块中,该块检查该值是否为nil。 因此appDelegate!.eventStore在此块中不为nil,因此不需要解包(?)。 我也尝试设置“!” 在此变量之后,如下所示:

appDelegate!.eventStore!

但它破坏了其他代码,因此在此代码周围出现错误:

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

用do {} catch {}语句将其括起来无济于事。

从外观上看,这更多地是与多余的参数有关,而不是与隐式解包的可选内容有关— Apple已为Swift 2更新了许多SDK,以避免传递对NSError对象的引用,而改用try

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

变成

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

作为一般规则,我避免像瘟疫那样隐式地解开可选的选项—几乎不需要它们,当它们确实存在时,您始终可以制作适当的非可选项。 尝试:

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)
}

这样一来,您就不会再使用隐式解包的可选eventStore可以确保在使用它时设置eventStore ,无论调用createReminder()可以处理该错误是什么,如果存在错误(您可能还会抛出一个错误而不是打印出来)未设置eventStore )。

好的,我不确定代码,但是我修复了错误,我仍然需要使用do-try-catch,但是就像这样:

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

如果检查nil的可选值

if (appDelegate!.eventStore != nil) {

你必须解开它的情况下,它不是nil

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

一种更合适的方法是使用可选绑定

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

appDelegate声明为可选的目的是什么?
默认情况下, AppDelegate类存在于任何应用程序中,并且永远不会为nil

暂无
暂无

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

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