ios - 在快速递归插入和更新数据库中的数据时面临内存问题

标签 ios objective-c swift swift3 ios-sqlite

我在数据库中插入和更新超过 100000 条数据。我正在使用 libsqlite3 框架。

问题:我面临的是每次插入内存增加到 4-5 MB 并且永远不会被释放。有更好的解决方案吗?

class DataBase{

let COMPANY_TABLE_NAME = "CompanyTable"

let fileName = "\(Constants.sharedInstance.DATABASE_NAME).sqlite"
let DBPath :String?

init() {

  DBPath  = FileManagement.sharedInstance.getDocumentFilePath(fileName)
}

private var dbPointer: OpaquePointer?

  let SQLITE_STATIC = unsafeBitCast(0, to: sqlite3_destructor_type.self)
  let SQLITE_TRANSIENT = unsafeBitCast(-1, to: sqlite3_destructor_type.self)



deinit
{
    sqlite3_close(dbPointer)

}

  func openDataBase(dbPath:String) -> OpaquePointer {


    var db: OpaquePointer?

    if sqlite3_open(dbPath, &db) == SQLITE_OK
    {
        print("Successfully opened connection to database at \(dbPath)")
    }
    else
    {
        //call to load database from file system
    }
    return db!
}


func inserttoCompanyTable(org_code: String , dataString:String)
{


    let insertSql = "INSERT INTO CompanyTable(orgcode,company_data) VALUES (?,?)"

    let insertStatement = prepareStatement(sql: insertSql)

    sqlite3_bind_text(insertStatement, 0, org_code, -1, SQLITE_TRANSIENT)
    sqlite3_bind_text(insertStatement, 1, dataString, -1,SQLITE_TRANSIENT)


    if sqlite3_step(insertStatement) != SQLITE_DONE {

        let errmsg = String(cString: sqlite3_errmsg(insertStatement))
        print("failure inserting foo: \(errmsg)")
    }

    sqlite3_finalize(insertStatement)
    sqlite3_close_v2(insertStatement)
}


func readAllData()-> [Company]
{

    var companiesArray:[Company] = [Company]()
    let selectQuery = "SELECT * FROM \(COMPANY_TABLE_NAME);"
    let selectStatement = prepareStatement(sql: selectQuery)

    while sqlite3_step(selectStatement) == SQLITE_ROW {

       if let comStr = sqlite3_column_text(selectStatement, 1)
       {
        let comString = String(describing: comStr)

        let comOBj = Mapper<Company>().map(JSONString: comString)
        companiesArray.append(comOBj!)
       }

    }

    return companiesArray
}


func isCompanyAvailable(org_code:String) -> Bool {



    let selectQuery = "SELECT * FROM \(COMPANY_TABLE_NAME) WHERE \(CompanyTable.orgcode) =?;"
    let selectStatement = prepareStatement(sql: selectQuery)

    sqlite3_bind_text(selectStatement, 0, org_code, -1, SQLITE_TRANSIENT)

    if sqlite3_step(selectStatement) == SQLITE_ROW
    {
        return true
    }
    else
    {
        return false
    }



 }


func updateTableData(company: Company)-> Bool  {

    let objString = company.toJSONString()
    let updateQuery = "UPDATE TABLE \(COMPANY_TABLE_NAME) SET \(CompanyTable.company_data) = \(objString) WHERE \(CompanyTable.orgcode) = \(company.orgCode);"
    let updateStatement = prepareStatement(sql: updateQuery)

    if sqlite3_step(updateStatement) == SQLITE_ROW
    {
        return true
    }
    else
    {
        return false
    }

}


func deleteFromCompanyTable(company:Company) {

     let deleteQuery = "DELETE FROM \(COMPANY_TABLE_NAME) WHERE \(CompanyTable.orgcode) = \(company.orgCode);"
    let deleteStatement = prepareStatement(sql: deleteQuery)

    if sqlite3_step(deleteStatement) == SQLITE_DONE
    {
        print("Successfully deleted row.")
    } else {

        print("Could not delete row.")
     }

}

func prepareStatement(sql: String) -> OpaquePointer {
    var statement: OpaquePointer?


    if sqlite3_open(DBPath, &self.dbPointer) == SQLITE_OK
    {
        print("Successfully opened connection to database at \(DBPath)")
        if sqlite3_prepare_v2(self.dbPointer, sql, -1, &statement, nil) == SQLITE_OK
        {

            return statement!
        }
        else
        {
            let errmsg = String(cString: sqlite3_errmsg(statement))
            print("error preparing select: \(errmsg)")
        }
    }


    return statement!
}

最佳答案

你会泄漏内存,因为你的大部分 sqlite3_prepare_v2 调用后面没有相应的 sqlite3_finalize电话。每次成功准备 SQL 语句时,都必须确保在完成该语句后完成该语句。

关于ios - 在快速递归插入和更新数据库中的数据时面临内存问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41360254/

相关文章:

ios - 当触地按钮( subview )时,不要处理 super View 上的平移手势

ios - iOS6 中的 MapView 在北纬 > 75 时不会显示某些缩放级别

javascript - UIWebView、缩放和 elementFromPoint

ios - 我可以根据 map View 上已有的路线获取大概的行程时间吗?

ios - 仅在某些 iPhone 5 和 6 上出现网站错误

iOS模拟器不显示应用程序

ios - 使用缓存的 UIView 设置 tableView 中的单元格背景 View :willDisplayCell:forRowAtIndexPath:

ios - 原型(prototype)可重用 tableview 单元格渲染 subview 很差

ios - 从 UIImage 获取 CIImage (Swift)

ios - 通过 Swift 在 XCode 上加载 DICOM 图像