iOS8中的内存管理问题,目标C
这段代码在iOS 8之前对我有效,我已经在iOS 7.1中的3000个图像下载循环中对它进行了测试 但最近我的一些应用程序用户告诉我,在图像下载过程中,应用程序崩溃了 使用这种方式,现在只有200张图片正在下载,应用程序崩溃 我刚刚发现,每次下载图像时,大约有0.6到0.8 MB的内存在增加,大约200张图像应用程序崩溃后。 我必须同步下载图像,因为当我尝试以iOS8中的内存管理问题,目标C,ios,objective-c,iphone,memory-management,ios8,Ios,Objective C,Iphone,Memory Management,Ios8,这段代码在iOS 8之前对我有效,我已经在iOS 7.1中的3000个图像下载循环中对它进行了测试 但最近我的一些应用程序用户告诉我,在图像下载过程中,应用程序崩溃了 使用这种方式,现在只有200张图片正在下载,应用程序崩溃 我刚刚发现,每次下载图像时,大约有0.6到0.8 MB的内存在增加,大约200张图像应用程序崩溃后。 我必须同步下载图像,因为当我尝试以后台线程或异步模式下载图像,甚至尝试使用dispatch\u async(dispatch\u get\u main\u queue()方
后台线程
或异步模式
下载图像,甚至尝试使用dispatch\u async(dispatch\u get\u main\u queue()
方式下载图像时,进程会在几秒钟后启动,直到我使用的While循环结束
所以,请在这个问题上帮助我。我应该做些什么来解决它
我下载图像的代码是:
-(void) downloadImages
{
NSString *myDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
database = [dBName UTF8String];
if (sqlite3_open(database, &dbConnection) == SQLITE_OK)
{
sqliteQuery = [NSString stringWithFormat: @"SELECT ProductID FROM ProductDetails WHERE ImageDownloadStatus = 0"];
int i = 0;
if (sqlite3_prepare_v2(dbConnection, [sqliteQuery UTF8String], -1, &sQLStatement, NULL) == SQLITE_OK)
{
while (sqlite3_step(sQLStatement) == SQLITE_ROW)
{
@autoreleasepool
{
temp = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(sQLStatement, 0)];
NSString *imageURL = [NSString stringWithFormat:@"http://xxxxxxxxxxxxxxx.jpg",clientSite,temp];
myImage = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]];
NSString *imagePath = [NSString stringWithFormat:@"%@/%@.jpg",myDirectory,temp];
NSData *imageData = [NSData dataWithData:UIImageJPEGRepresentation(myImage, 1.0f)];
[imageData writeToFile:imagePath atomically:YES];
sqliteQuery2 = [NSString stringWithFormat: @"UPDATE ProductDetails SET ImageDownloadStatus = 1 WHERE ProductID = \'%@\'",temp];
if (sqlite3_prepare_v2(dbConnection, [sqliteQuery2 UTF8String], -1, &sQLStatement2, NULL) == SQLITE_OK)
{
if (sqlite3_step(sQLStatement2) == SQLITE_DONE)
sqlite3_finalize(sQLStatement2);
}
[self performSelectorInBackground:@selector(updateUILabels) withObject:nil];
i = i + 1;
}
}
sqlite3_finalize(sQLStatement);
}
sqlite3_close(dbConnection);
}
}
-(void) updateUILabels
{
@autoreleasepool
{
progressCounter.hidden = NO;
lblProgressStatus.hidden = NO;
spinner.hidden = NO;
[spinner startAnimating];
lblProgressStatus.text = @"Synchronising Product Images...";
lblProgressCounter.text = [NSString stringWithFormat:@"%d / %d”, i,total];
}
}
您应该在后台执行
downloadImages
方法,在主线程中执行updateIlabels
方法。您可以使用dispatch_async(dispatch_get_main_queue(),^{[self updateIlabels]};
或[self performSelectorOnMainThread:@selector(updateIlabels:)和object:nil waitUntilDone:NO];
在主线程中执行更新的ilabels
通常,始终在后台线程中执行长时间运行的操作(使用GCD、NSOperations或blocks),并始终在主线程上执行更新UI的函数。首先阅读有关performSelectorInBackground的内容。也不要从后台线程更新UI元素。@AndreasZ我只需检查一下
[self-performSelectorOnMainThread:@selector(updateUILabels:)with object:nil waitUntilDone:NO];
但UI未更新:(dowloadImages是否在后台线程上运行?如果不简单调用[self-updateUILabels]。但是,如果您不使用后台线程下载图像,您将阻止主线程。@AndreasZdownloadImages
正在主线程上运行。我如何阻止主线程您应该在后台线程上执行downloadImages。我在您的问题中写道“我必须同步下载图像,因为当我尝试以后台线程或异步模式下载图像,甚至尝试使用dispatch_async(dispatch_get_main_queue()方式)时,该过程会在几秒钟后开始,直到我使用的While循环结束。“当你说你正在使用的while循环已经结束时,你是什么意思?