0

我将图像存储在服务器中。然后我获取图像并通过图像 URL 保存到 db1.sqlite 文件。图像保存到 db1.sqlite 文件,如 URL。如何显示保存的 URL 中的图像。product_image 具有 imageURL 路径。

代码:

sqlite 表结构:

CREATE TABLE "product" ("id" INTEGER PRIMARY KEY  NOT NULL , "cat_id" INTEGER NOT NULL , "product_image" VARCHAR NOT NULL , "order_by" INTEGER NOT NULL )

插入代码:

const char *sqlInsert = [[NSString stringWithFormat:@"insert into product (id, cat_id,product_image,order_by) values ('%@','%@','%@','%@')", [tuser objectForKey:@"id"], [tuser objectForKey:@"cat_id"],[tuser objectForKey:@"product_image"],[tuser objectForKey:@"order_by"]] cStringUsingEncoding:NSUTF8StringEncoding];

NSLog(@"product insert %s", sqlInsert);

if(sqlite3_prepare_v2(database, sqlInsert, -1, &addStmt, NULL) != SQLITE_OK)
    NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(database));

if(SQLITE_DONE != sqlite3_step(addStmt))
    NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(database));

图片抓取:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//NSLog(@"docs dir is %@", documentsDirectory);

NSString *path = [documentsDirectory stringByAppendingPathComponent:@"db1.sqlite"];
//NSLog(@"filepath %@",path);

mArray = [[NSMutableArray alloc]init];
if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) {

    const char *sql = "SELECT id,cat_id,product_image FROM product order by order_by";

    NSLog(@"sql is %s",sql);

    sqlite3_stmt *statement;
    //  int catID = 0;
    if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {
        // We "step" through the results - once for each row.
        while (sqlite3_step(statement) == SQLITE_ROW) {

            int length = sqlite3_column_bytes(statement, 2);
            NSData *imageData = [NSData dataWithBytes:sqlite3_column_blob(statement, 2) length:length];

            UIImage *image = [UIImage imageWithData:imageData];

            [mArray addObject:image];

            [image release];
        }
    }
    sqlite3_finalize(statement);
}
else {
    sqlite3_close(database);
    NSAssert1(0, @"Failed to open database with message '%s'.", sqlite3_errmsg(database));
    // Additional error handling, as appropriate...
}
4

1 回答 1

1

和你离线聊天,我发现那product_image不是一个NSData。(我从后来的存在错误地推断出sqlite3_column_blob您正在尝试存储二进制数据,但事实并非如此。)显然product_image是包含 URL 的字符串。所以将其存储为字符串。并且永远不要stringWithFormat在您的 SQL 语句中使用,而是使用sqlite3_bind_xxx带有?占位符的函数,例如:

const char *sqlInsert = "insert into product (id, cat_id, product_image, order_by) values (?, ?, ?, ?)";

if (sqlite3_prepare_v2(database, sqlInsert, -1, &addStmt, NULL) != SQLITE_OK)
    NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(database));

if (sqlite3_bind_int(addStmt, 1, [[tuser objectForKey:@"id"] intValue]) != SQLITE_OK)
    NSAssert1(0, @"Error binding 1. '%s'", sqlite3_errmsg(database));

if (sqlite3_bind_int(addStmt, 2, [[tuser objectForKey:@"cat_id"] intValue]) != SQLITE_OK)
    NSAssert1(0, @"Error binding 2. '%s'", sqlite3_errmsg(database));

if (sqlite3_bind_text(addStmt, 3, [[tuser objectForKey:@"product_image"] UTF8String], -1, NULL) != SQLITE_OK)
    NSAssert1(0, @"Error binding 3. '%s'", sqlite3_errmsg(database));

if (sqlite3_bind_int(addStmt, 4, [[tuser objectForKey:@"order_by"] intValue]) != SQLITE_OK)
    NSAssert1(0, @"Error binding 4. '%s'", sqlite3_errmsg(database));

if (SQLITE_DONE != sqlite3_step(addStmt))
    NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(database));

// don't forget to finalize

sqlite3_finalize(addStmt);

如果这样做,您也必须更改检索图像的代码。例如,您有:

while (sqlite3_step(statement) == SQLITE_ROW) {

    int length = sqlite3_column_bytes(statement, 2);
    NSData *imageData = [NSData dataWithBytes:sqlite3_column_blob(statement, 2) length:length];

    UIImage *image = [UIImage imageWithData:imageData];

    [mArray addObject:image];

    [image release];
}

几个想法:

  1. [image release]是一个过度释放。imageWithData返回一个对象,因此autorelease您不需要/不想释放它。这种错误可能是灾难性的,所以我建议您通过静态分析器运行代码以帮助识别这些错误(通过从“产品”菜单中选择“分析”,或按command+ shift+ B)。静态分析器生成的警告应该为零。分析器是识别编程错误的非常有用的工具,因此请使用这个出色的工具。

  2. 但是,前面的观点没有实际意义,因为您没有将实际图像存储在 中NSData,而是将 URL 存储在字符串中,因此您应该sqlite3_column_text改用 。

  3. 一旦你将const char *你得到的转换sqlite3_column_text成 a NSString,你就想要获取该字符串并创建一个 URL,例如:

    NSURL *url = [NSURL URLWithString:urlStringFromDatabase];
    
  4. 然后,您可以将其与 , 之类的类别NSURL结合使用,以异步检索图像(并执行所有适当的缓存等)。UIImageViewSDWebImage

    [imageView setImageWithURL:url
              placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
    
  5. 并且,冒着重复自己的风险,您的图像检索代码检查 SQLite 函数是否返回,例如SQLITE_OK,但如果没有,则您没有显示sqlite3_errmsg. 调试应用程序时,请务必查看此内容。它将为您节省数小时的开发/调试时间。

于 2013-08-22T16:15:36.367 回答