我正在使用GRDB库将SQLite与我的iOS应用程序项目集成。我在AppDelegate.swift中声明了DatabaseQueue对象,如下所示:
var DB : DatabaseQueue!
在同一文件中,我提供了一个将上述对象连接到SQLite数据库的功能,该功能在应用程序开始运行时会调用。我已经能够在我的一个控制器中使用它,而不会出现问题(例如,应用程序在使用连接到它的数据库运行时没有问题),就像这样:
var building : Building?
do {
try DB.write { db in
let building = Building.fetchOne(db, "SELECT * FROM Building WHERE number = ?", arguments: [bldgNumber])
}
} catch {
print(error)
}
但是,在另一个控制器中,相同的构造遇到错误,
Value of optional type 'DatabaseQueue?' must be unwrapped to refer to member 'write' of wrapped base type 'DatabaseQueue'
唯一的区别(当然,除了代码之外)是do-catch块内有return语句,因为后者在函数(用于numberOfRowsInSection的tableView)内,该函数应该返回整数。错误的代码部分如下所示。
var locsCountInFloor : Int
do {
try DB.write { db in
if currentBuilding!.hasLGF == true {
locsCountInFloor = IndoorLocation.filter(bldg == currentBuilding! && level == floor).fetchCount(db)
} else {
locsCountInFloor = IndoorLocation.filter(bldg == currentBuilding! && level == floor + 1).fetchCount(db)
}
return locsCountInFloor
}
} catch {
return 0
}
任何帮助将不胜感激!
答案 0 :(得分:0)
通常,当您在Swift中遇到泛型类型的问题时,错误消息没有帮助。
这是真正的问题:
DB.write
的参数和返回类型是通用的。它具有类型参数T
。闭包参数的返回类型为T
,而write
方法本身返回T
。
您要传递的闭包不只是一个表达式。这是一个多语句闭包。 Swift不会从闭包中的语句推断出多语句闭包的类型。出于实际原因,这仅仅是编译器的一个局限。
您的程序未明确指定类型T
或提供了其他约束,这些约束使Swift可以推断出具体类型。
程序的这些特征意味着Swift不知道T
使用的具体类型。因此,编译器的类型检查器/推断器将失败。您可能会收到有关此问题的错误消息。 (可能是一条难以理解的消息,但可能至少与之相关)。
但这不是您得到的,因为您将DB
声明为DatabaseQueue!
。
由于DB
是一个隐式解包的可选内容,因此类型检查器会通过自动地对其进行解包(您可能会猜到)来特别地处理它(如果这样做),当否则将不进行类型检查。通过其他所有方式,DB
的类型只是普通的DatabaseQueue?
,是常规的Optional
。
在这种情况下,由于上述错误,即使使用自动展开,该语句也不会进行类型检查:Swift无法推断出具体类型来代替T
。由于该语句不会以任何一种方式进行类型检查,因此Swift不会为您插入展开内容。然后它继续进行,就好像DB
被声明为DatabaseQueue?
。
由于DatabaseQueue?
没有write
方法(因为Optional
没有write
方法),所以呼叫DB.write
是错误的。因此,Swift想打印一条错误消息。但是它“有帮助”地看到包装类型DatabaseQueue
确实具有一种write
方法。至此,它已经完全忘记了DB
被声明为隐式解包。因此,它告诉您打开DB
进入write
方法,即使,即使在此语句中没有遇到其他错误,它也会自动完成。< / p>
因此,无论如何,您需要告诉Swift T
使用哪种类型。我怀疑您是想这样说:
var locsCountInFloor: Int
do {
locsCountInFloor = try DB.write { db in
...
将DB.write
调用的结果分配给外部locsCountInFloor
就足以解决该错误,因为您已经明确定义了locsCountInFloor
的类型。由此,Swift可以推断出对DB.write
的调用的返回类型,以及闭包的类型。