我检测Singleton实例上是否存在连接,如果不存在,它将在应用程序启动时打开一个新连接。然而,理想情况下,我希望在首次创建Singleton时激发open函数,而不必显式调用它并将其分配给类中的某个变量。
我现在拥有代码的方式违背了共享Singleton的目的,因为我只访问静态连接对象。当我尝试将静态conn
更改为实例变量时,我得到错误Instance member 'conn' cannot be used on type 'DBConnection'
非工作代码
class DBConnection {
static let shared = DBConnection()
var conn: Connection? = nil
private init() { }
static func open(dbPath: URL) throws {
var dbConnections: [Connection] = []
do {
let dbConnection = try Connection("(dbPath)/db.sqlite3")
dbConnections.append(dbConnection)
print("found connection, (dbConnections)")
} catch {
throw SQLiteDBError.couldNotOpenConnection
}
self.conn = dbConnections[0]
print("successfully opened connection")
}
}
如何在init上调用Singleton类中的私有函数并将其分配给某个变量?
当前工作代码
class DBConnection {
static let shared = DBConnection()
static var conn: Connection?
private init() { }
static func open(dbPath: URL) throws {
var dbConnections: [Connection] = []
do {
let dbConnection = try Connection("(dbPath)/db.sqlite3")
dbConnections.append(dbConnection)
print("found connection, (dbConnections)")
} catch {
throw SQLiteDBError.couldNotOpenConnection
}
self.conn = dbConnections[0]
print("successfully opened connection")
}
}
主应用程序初始化
@main
struct MyApp: App {
init() {
if DBConnection.conn != nil {
do {
try DBConnection.open(dbPath: FileManager.default.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask)[0])
} catch {
print("error")
}
} else {
print("Connection already existed")
}
}
....
}
当我试图将静态连接更改为实例变量时,我会得到错误
Instance member 'conn' cannot be used on type 'DBConnection'
考虑到您如何使用open
:,这是有意义的
try DBConnection.open(dbPath: FileManager.default.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask)[0])
现在,open
是DBConnection
的一个静态方法,这意味着您可以在不需要类实例的情况下调用它。它类似于";类方法";在Objective-C中。但在你破碎的代码中,你有:
var conn:连接?=无
因此conn
是一个实例变量,即一个仅存在于类实例上下文中的变量。一个快速的解决方案是使open
非静态:
func open(dbPath: URL) throws {
然后使用共享实例调用它:
try DBConnection.shared.open(dbPath: FileManager.default.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask)[0])
(注意添加了shared
。(
然而,理想情况下,我希望在首次创建Singleton时激发open函数,而不必显式调用它并将其分配给类中的某个变量。
如果希望在创建单例时打开连接,可以从初始化器内部调用open
。
另一个方向是让conn
和open
都保持静态,这样open
就可以访问conn
,并让类本身成为singleton。然后可以消除shared
变量。
然而,我认为最好的选择是如上所述,使conn
和open
非静态,和去掉shared
实例,而只跟踪您创建的DBConnection
对象。