我有一种方法可以将一堆UIImages保存为JPG并且我的应用程序崩溃,我相信由于内存未被释放。我正在使用UIImageJPEGRepresentation来保存图像,我将它包装在自动释放池中,但它似乎没有用。
for (Images *anImage in images) {
NSAutoreleasePool* p = [[NSAutoreleasePool alloc] init];
NSString *fileName = [NSString stringWithFormat:@"%@-%i-%i-%i.jpg", appDelegate.currentUserName, appDelegate.reportId, aDefect.defectId, i];
[UIImageJPEGRepresentation(anImage.image, 1) writeToFile:localImagePath atomically:NO];
[p drain];
i++;
}
当我运行上面的代码时,分析器向我显示正在使用越来越多的内存,并最终崩溃。如果我删除该行 - [UIImageJPEGRepresentation(anImage.image,1)writeToFile:localImagePath atomically:NO];它工作正常。
FYI循环遍历NSManagedObjects数组。
任何帮助将不胜感激!感谢
以下是根据建议的新代码 -
- (void) convertImages {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Report" inManagedObjectContext:context];
NSPredicate *predicate = [NSPredicate
predicateWithFormat:@"status != %@", @"Leads"];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:predicate];
[fetchRequest setIncludesPropertyValues:NO];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (Report *aReport in fetchedObjects) {
appDelegate.reportId = [aReport.reportId intValue];
NSArray *defects = [self getAllItemDefects];
for (ItemDefect *anItemDefect in defects) {
NSArray *defectImages = [self getImages:[anItemDefect.itemDefectId intValue] isMainImage:NO];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^(void) {
int i = 0;
for (Images *anImage in defectImages) {
NSString *fileName = [NSString stringWithFormat:@"%@-%i-%i-%i.jpg", appDelegate.currentUserName, [aReport.reportId intValue], [anItemDefect.itemDefectId intValue], i];
NSString *localImagePath = [documentsDirectory stringByAppendingPathComponent:fileName];
[UIImageJPEGRepresentation(anImage.image, 1) writeToFile:localImagePath atomically:NO];
i++;
}
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"FINISH: do eventual operations");
});
});
}
}
}
这给了我这个错误 -
如果我在调度块中加载了缺陷图像数组,它就什么都不做。谢谢你的帮助。
编辑 - 由于CoreData不是线程安全的,我已经声明了新的FetchRequests和ObjectContexts来解决这个问题。我不再遇到错误的访问错误,但我又回到了内存不足的状态。我为你简化了代码,但它在这种状态下产生了内存泄漏 -
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^(void) {
NSFetchRequest *backgroundFetchRequest = [[NSFetchRequest alloc] init];
NSManagedObjectContext *backgroundContext = [[[NSManagedObjectContext alloc] init] autorelease];
[backgroundContext setPersistentStoreCoordinator:persistentStoreCoordinator];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Images" inManagedObjectContext:backgroundContext];
NSPredicate *predicate = [NSPredicate
predicateWithFormat:@"itemDefectId=%i AND reportId=%i AND isMainImage=%i", itemDefectId, appDelegate.reportId, NO];
[backgroundFetchRequest setEntity:entity];
[backgroundFetchRequest setIncludesPropertyValues:NO];
[backgroundFetchRequest setPredicate:predicate];
NSArray *defectImages = [backgroundContext executeFetchRequest:backgroundFetchRequest error:&error];
NSMutableArray *images = [[NSMutableArray alloc] init];
for (Images *anImage in defectImages) {
[images addObject:anImage.image];
}
[images release];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"FINISH: do eventual operations");
});
});
答案 0 :(得分:0)
这不是一个好的解决方案,请使用GCD:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
for (int i=0; i<[images count]; i++) {
dispatch_async(queue, ^(void) {
Images *anImage = (Images *)[images objectAtIndex:i];
NSString *fileName = [NSString stringWithFormat:@"%@-%i-%i-%i.jpg", appDelegate.currentUserName, appDelegate.reportId, aDefect.defectId, i];
[UIImageJPEGRepresentation(anImage.image, 1) writeToFile:localImagePath atomically:NO];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"FINISH to write image %d", i);
});
});
}
此外,在您的代码中,文件名始终相同,不会更改,也不会使用。你的代码是不完整的?
但是,请使用调度程序进行异步处理。