下面是我的源代码,每次执行该函数时,内存使用量都会急剧增加。请指出问题是什么。
func loadfontsFromDatabase(code:String)->[String] {
let documentsPath : AnyObject = NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask,true)[0] as AnyObject
let databasePath = documentsPath.appending("/bsmcoding.sqlite")
let contactDB = FMDatabase(path: databasePath as String)
var c:[String]=[]
let querySQL = "SELECT FONT FROM BSMCODE WHERE BSMCODE.CODE = '\(code)' ORDER BY NO DESC"
NSLog("query:\(querySQL)")
let results:FMResultSet? = Constants.contactDB?.executeQuery(querySQL, withArgumentsIn: nil)
while (results?.next())! {
c.append((results?.string(forColumn: "FONT"))!)
}
results?.close()
return c
}
答案 0 :(得分:0)
这里没有什么可以解释任何实质性的记忆丧失。我建议使用Xcode 8中的“调试内存图”功能来识别正在创建和未发布的对象,但我怀疑问题出现在代码的其他地方。或者使用Instruments来跟踪它的泄漏和调试。请参阅https://stackoverflow.com/a/30993476/1271826。
但这里存在不相关的问题:
您正在创建本地contactDB
,但您永远不会打开它而您永远不会使用它。它将在例程退出时释放,但如果您打算使用Constants.contactDB
,则完全没有必要。
我建议不要在构建SQL时使用字符串插值。使用?
占位符并将code
作为参数传递。如果代码包含无法在SQL语句中表示的内容,则更安全。 (如果用户提供code
,则尤其如此,在这种情况下,您可能会受到SQL注入攻击或可能导致崩溃的无辜输入错误的影响。)
例如,您可以执行以下操作:
func loadfontsFromDatabase(code: String) -> [String] {
var c = [String]()
let querySQL = "SELECT FONT FROM BSMCODE WHERE BSMCODE.CODE = ? ORDER BY NO DESC"
let results = try! Constants.contactDB!.executeQuery(querySQL, values: [code])
while results.next() {
c.append((results.string(forColumn: "FONT"))!)
}
return c
}
如果您不喜欢强制解包,可以根据需要进行可选的展开,但在开发阶段调试时,如果出现一些逻辑错误(例如contactDB
打开,SQL不正确等等。但是如果需要,您可以执行可选绑定并添加必要的guard
语句。但是,不要只做可选绑定并静默返回一个值,表明一切都是copacetic,如果你没有达到你的预期,你就会遇到调试问题,即追踪问题。
但关键是要避免直接在SQL中插入值。使用?
占位符。