变量不存储赋予它的内容 - Swift 3

时间:2016-11-23 19:13:09

标签: ios swift swift3

我将从SQLite DB中获取的日期存储到Date Var时遇到问题,我试图将从DB转换为ResultTask.AlarmDate后的日期保存到?到目前为止。

当我尝试从ResultTask.AlarmDate?删除nil时,它存储的数据很好,但是当我有一个没有警报的任务时,我收到错误,因为我想存储Console它没有警报时的var,并尝试了多种其他方法来修复它但没有任何效果。

我在问题发生后立即提出了一个断点并使用nil来查看数据并感到困惑,因为当我打印我要在var中存储的内容时显示的数据但是var仍然是Console,全部如下所示。

备注

从数据库获取数据的代码工作正常,我正在使用Objective-C FM数据库库,结果可以在下面的.toDate()中找到。

String是我使用的AppDelegate.swift的扩展程序,代码位于Task中,如下所示,它运行正常。

Task.swift变量类型是我在func GetTasks() -> [Task]{ var Tasks : [Task] = [Task]() let dirPaths = NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask, true) let docsDir = dirPaths[0] databasePath = (docsDir + "/" + "Tasks.db") as NSString let TaskRecorderDB = FMDatabase(path: databasePath as String) if (TaskRecorderDB?.open())! { let querySQL = "Select * from 'Tasks' ORDER BY Priority DESC" let results:FMResultSet? = TaskRecorderDB?.executeQuery(querySQL, withArgumentsIn: nil) while results!.next() { var ResultTask : Task! = Task() ResultTask.ID = Int((results?.int(forColumn: "ID"))!) ResultTask.FileName = results?.string(forColumn: "FileName") ResultTask.Name = results?.string(forColumn: "Name") ResultTask.Categorie = Int((results?.int(forColumn: "Categorie"))!) ResultTask.Priority = Int((results?.int(forColumn: "Priority"))!) ResultTask.AlarmDate? = (results?.string(forColumn: "Alarm").toDate())! //Break point ResultTask.Repeat? = (results?.string(forColumn: "Repeat"))! ResultTask.Completed = Int((results?.int(forColumn: "Completed"))!).toBool() if(ResultTask.Completed == false){ Tasks.append(ResultTask) } ResultTask = nil } TaskRecorderDB?.close() } else { print("Error #DB06: \(TaskRecorderDB?.lastErrorMessage())") } return Tasks } 文件中创建的,以方便工作,它工作得很好&如下所示。

功能:

(lldb) print (results?.string(forColumn: "Alarm").toDate())!
(Date) $R0 = 2016-11-23 17:21:00 UTC
(lldb) print ResultTask.AlarmDate
(Date?) $R1 = nil
(lldb) 

控制台:

extension String {
    func toDate () ->Date! {
        var FinalDate : Date! = nil
        if (self != ""){
            let DateFormatter : Foundation.DateFormatter = Foundation.DateFormatter()
            DateFormatter.locale = Locale.current
            DateFormatter.dateFormat = "y-MM-dd_HH-mm-ss"
            FinalDate = DateFormatter.date(from: self)!
        }

        return FinalDate
    }
}

AppDelegate.swift:

import Foundation

class Task : NSObject {
    var ID : Int! = nil
    var FileName : String! = nil
    var Name : String! = nil
    var Categorie : Int! = nil
    var Priority : Int! = nil
    var AlarmDate : Date! = nil
    var Repeat : String! = nil
    var Expired : Bool! = nil
    var Completed : Bool! = nil
}

Task.swift:

.toDate()

提前致谢。

编辑@KaraBenNemsi:

我按照你的说法更新var AlarmDate : Date?

&安培;在任务中,我使用了var AlarmDate : Date! = nil而不是Task.swift(我现在没有使用你ResultTask.AlarmDate = results?.string(forColumn: "Alarm").toDate()中的其他提示,因为我需要在应用中更改很多其他代码)。

使用了fatal error: unexpectedly found nil while unwrapping an Optional value,当任务没有警报时,我会在其中获得grep -m1 -c "UNSAT" res.txt

2 个答案:

答案 0 :(得分:1)

尝试在任务类中更改此行,因为它可以是可选的

来自这个

var AlarmDate: Date! = nil

到这个

var AlarmDate: Date?

然后使用此行设置闹钟

ResultTask.AlarmDate = results?.string(forColumn: "Alarm")?.toDate()

同样,变量名通常应以小写字母开头。

我也认为这条线是不必要的。你可以省略那一行。

ResultTask = nil

请同时将扩展名更改为

extension String {
func toDate() -> Date? {
    guard self != "" else {
         return nil
    }
    var finalDate: Date?
    let DateFormatter : Foundation.DateFormatter = Foundation.DateFormatter()
    DateFormatter.locale = Locale.current
    DateFormatter.dateFormat = "y-MM-dd_HH-mm-ss"
    finalDate = DateFormatter.date(from: self)
    return finalDate
   }
}

也许会尝试更多地了解期权的运作方式 https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html

增加: 您的课程任务应该看起来更像下面。但是你必须在其他地方改变代码。它还会强制您在初始化任务对象时传递构造函数中的所有必需参数。

class Task {
    var id: Int
    var fileName: String
    var name: String
    var category: Int
    var priority: Int
    var alarmDate: Date?
    var repeating: String
    var expired: Bool
    var completed: Bool

     init(id: Int, fileName: String, name: String, category: Int, priority: Int, repeating: String, expired: Bool, completed: Bool) {
        self.id = id
        self.fileName = fileName
        self.name = name
        self.category = category
        self.priority = priority
        self.repeating = repeating
        self.expired = expired
        self.completed = completed
    }
}

这里也是Swift风格指南的链接:

https://github.com/raywenderlich/swift-style-guide

答案 1 :(得分:0)

将您的任务更改为

var AlarmDate : Date?

然后这样做

if let alarm = results?.string(forColumn: "Alarm").toDate() {
    ResultTask.AlarmDate = alarm
}

如果在解包结果时找到任何nil,则不会设置ResultTask.AlarmDate的值。