我在特定的视图控制器上生成(可能)非常慢且效率低的拼贴画。它需要永远加载,所以我正在寻找建议,既可以加快我的SQLite查询(它正在搜索已保存图像的BLOB),也可以在 viewcontroller加载后调用来调用SQL查询方法,以及然后我会在加载时放一个活动指示器。
以下是代码段。
viewDidLoad
:
- (void)viewDidLoad
{
//generate photo collage
wineryName = theWineOfCurrentWinery.winery;
[self obtainImagesForWines:wineryName];
//lots of other stuff
}
obtainImagesForWines
功能。这是控制16个UIImageViews中的一个显示的照片,它们有4x4块:
- (void) obtainImagesForWines:(NSString *)theWineryName {
sqlite3_stmt *stmt=nil;
sqlite3 *cruddb;
//sql command
const char *sql = "SELECT photo FROM wines WHERE winery=? AND photo NOT NULL ORDER BY RANDOM() LIMIT 16";
//Open db
sqlite3_open([path UTF8String], &cruddb);
int j=0;
if(sqlite3_prepare_v2(cruddb, sql, -1, &stmt, NULL) == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, [theWineryName UTF8String], -1, SQLITE_TRANSIENT);
while(sqlite3_step(stmt) == SQLITE_ROW) {
UIImage *winePhoto;
NSData *data = [[NSData alloc] initWithBytes:sqlite3_column_blob(stmt, 0) length:sqlite3_column_bytes(stmt, 0)];
if (data) {
winePhoto = [UIImage imageWithData:data];
}
switch (j) {
case 0:
image1.image = winePhoto;
break;
case 1:
image2.image = winePhoto;
break;
case 2:
image3.image = winePhoto;
break;
case 3:
image4.image = winePhoto;
break;
case 4:
image5.image = winePhoto;
break;
case 5:
image6.image = winePhoto;
break;
case 6:
image7.image = winePhoto;
break;
case 7:
image8.image = winePhoto;
break;
case 8:
image9.image = winePhoto;
break;
case 9:
image10.image = winePhoto;
break;
case 10:
image11.image = winePhoto;
break;
case 11:
image12.image = winePhoto;
break;
case 12:
image13.image = winePhoto;
break;
case 13:
image14.image = winePhoto;
break;
case 14:
image15.image = winePhoto;
break;
case 15:
image16.image = winePhoto;
break;
default:
NSLog(@"wtf?");
}
j++;
}
}
else {
printf("I can't get the wine photo by ID!!: %s\n", sqlite3_errmsg(cruddb));
}
sqlite3_finalize(stmt);
sqlite3_close(cruddb);
}
答案 0 :(得分:1)
您可以在显示/存储图像时尝试缩小图像尺寸。我不确定,但我认为你在你的imageview中展示了一个非常大的图像。我相信你正在尝试显示16个图像缩略图。如果是这样,请尝试压缩图像。
一种可能更好的选择,当您存储图像时,您可以将实际图像与缩略图版本一起存储,因此当您显示较小的图像时,请使用较小的图像。等等。
UIImageJPEGRepresentation(image,compressionRatio);
这应该允许您压缩图像。或者,如果你想像这样调整大小:
UIImage *yourImage = [UIImage imageWithData:yourdata];
UIImageView *imageView = [[UIImageView alloc] initWithImage:yourImage];
UIImageView.frame = CGRectMake(0, 0, yourImage.size.width / 2, yourImage.size.height / 2);
希望这有帮助!!
<强>更新:强>
关于使用sqlite BLOB存储图像的stackoverflow似乎有很多争论,这里涉及到一个巨大的性能问题。一个这样的例子here。
我自己有多个场景,我必须保存图像。我所做的(我所有的解决方案)是将图像保存到文档文件夹,然后核心数据(如果您愿意,还有sqlite)存储对图像位置和名称的引用。这样,DB的读取时间降低,时间也降低。
我使用以下函数作为获取文档位置的通用方法:
- (NSString *)getFileLocation {
// Get all available file system paths for the user
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// Get the "Documents" directory path - it's the one and only on iPhone OS
NSString *documentsPath = [paths objectAtIndex:0];
// Specify the file name, appending it to documentsPath above
NSString *savedFileName = [documentsPath stringByAppendingPathComponent:@"Location.plist"];
// We're done
return savedFileName;
}
然后将文件位置作为字符串保存到DB。我建议使用核心数据以获得更好的性能。
答案 1 :(得分:1)
您应该添加代码,这需要花费一些时间来处理ViewDidAppear
等其他方法
或者请在后台运行它,当你尝试从后台线程udpate UI时会导致更麻烦。所以我会选择第一个选项并将代码添加到ViewDidAppear
函数中。
如果你想我可以发布代码在后台运行它,但我会误导你,因为我会推动你进入一个会迫使你对你的代码进行更多修改的轨道。
答案 2 :(得分:0)
为了在后台运行此方法(换句话说“在视图加载后”),我在viewDidLoad
中使用了以下代码:
[self performSelectorInBackground:@selector(obtainImagesForWines) withObject:nil];