【发布时间】:2016-11-23 19:13:08
【问题描述】:
我在将从 SQLite DB 获取的日期存储到 Date Var 时遇到问题,我正在尝试将来自 DB 的日期从 String 转换为 Date 后保存到 ResultTask.AlarmDate。
当我尝试从ResultTask.AlarmDate? 中删除? 时,它可以很好地存储数据,但是当我有一个没有警报的任务时,我收到一个错误,因为我想在没有警报时将nil 存储为var ,并尝试了多种其他方法来修复它,但没有任何效果。
我在问题发生后立即设置了一个断点并使用Console 查看数据并感到困惑,导致当我打印我试图存储在 var 中的内容时显示的数据但 var 仍然是 @987654328 @,如下所示。
备注
从 DB 获取数据的代码运行良好,我使用的是 Objective-C FM-Database 库,结果见下面的Console。
.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)
AppDelegate.swift:
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
}
}
Task.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
}
提前致谢。
为@KaraBenNemsi 编辑:
我按照你说的更新.toDate()。
& 在任务中我使用了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。
【问题讨论】:
-
我强烈建议清理(部分矛盾的)问号和感叹号的混乱。如果一个属性应该有一个值,则将其视为非可选的,否则视为真正的可选。声明为隐式展开的可选属性是最糟糕的妥协。
-
@vadian 我不擅长,我讨厌它,它让我头疼。但我玩了很多次,用它做了很多情况,但大多数情况下它给了我错误,我无法运行应用程序,或者它工作但不像我想要的那样。
-
据我所知,它仍然在
ResultTask.AlarmDate = results?.string(forColumn: "Alarm").toDate()这一行崩溃。可以发一下string(forColumn: String)函数的代码吗? -
@KaraBenNemsi 它不是来自我使用的 FMDB 库中的我
-
@AbdulrahmanAlattas 你确定你在这行
ResultTask.AlarmDate = results?.string(forColumn: "Alarm").toDate()的末尾漏掉了!。你可以试试这条线ResultTask.AlarmDate = results?.string(forColumn: "Alarm")?.toDate()