【发布时间】:2011-08-24 21:49:02
【问题描述】:
我的问题是关于核心数据和内存使用情况。我以前使用过核心数据,但这次数据量更高,这让我意识到还有很多东西要知道。我看到还有其他几个类似的帖子,我从他们那里得到了有趣的信息,但是在应用之后我的应用程序仍然崩溃。我已经处理这个问题一个星期了。请有人帮忙。
基本上我有三个后续类似的循环,分别是 64、15 和 17 次迭代。他们在模拟器上工作正常。在几台 iPad 上进行了测试,它们收到内存警告,并且在同一迭代中崩溃(第一个循环的第 34 号)。在 iPad 2 上测试它会在第二个循环的 14 号崩溃。 Instruments 显示实时和整体的内存使用量约为 1.5 MB。有几 KB 的泄漏。
循环执行以下操作(代码如下)
- 使用核心数据执行提取
- 为每条记录获取一个存储为行属性属性(字符串)的参数
- 调用一个接受该参数并返回数据(大约数百 KB)的过程
- 将这些数据存储在同一行的另一个属性属性(Transformable)中
很常见的任务不是吗?
现在,由于我遇到了内存问题,我尝试使用我可以使用的所有已知(由我自己)工具,它们是:
- 尽快释放拥有的对象
- 为不拥有的对象创建自动释放池并尽快排空它们
- 尽快保存上下文
- 尽快将对象变成故障
应用所有这些技术后,我得到了一个令人兴奋的结果:应用程序在与之前完全相同的时间点崩溃。
这是代码。
- (void) myMainProcedure {
[self performLoop1];
[self performLoop2]; // Similar to loop1
[self performLoop3]; // Similar to loop1
}
- (void) performLoop1 {
NSError * error = nil;
NSAutoreleasePool * myOuterPool;
NSAutoreleasePool * myInnerPool;
NSManagedObjectContext * applicationContext = [[[UIApplication sharedApplication] delegate] managedObjectContext];
[applicationContext setUndoManager:nil];
NSEntityDescription * myEntityDescription = [NSEntityDescription entityForName:@"EntityName"
inManagedObjectContext:applicationContext];
NSFetchRequest * myFetchRequest = [[NSFetchRequest alloc] init];
[myFetchRequest setEntity:myEntityDescription];
NSString * column = @"columnName";
NSPredicate * aWhereClause = [NSPredicate predicateWithFormat:
@"(%K = %@)", column, [NSNumber numberWithInt:0]];
[myFetchRequest setPredicate: aWhereClause];
myOuterPool = [[NSAutoreleasePool alloc] init];
NSArray * myRowsArray = [applicationContext executeFetchRequest:myFetchRequest
error:&error];
NSMutableArray * myRowsMutableArray = [[NSMutableArray alloc] initWithCapacity:0];
[myRowsMutableArray addObjectsFromArray: myRowsArray];
[myOuterPool drain];
[myFetchRequest release];
EntityName * myEntityRow;
int totalNumberOfRows = [myRowsMutableArray count];
myOuterPool = [[NSAutoreleasePool alloc] init];
for (int i = 0; i < totalNumberOfRows; i++) {
myInnerPool = [[NSAutoreleasePool alloc] init];
myEntityRow = [myRowsMutableArray objectAtIndex:0];
NSString * storedSmallAttribute = myEntityRow.smallAttribute;
UIImageView * largeData = [self myMethodUsingParameter: smallAttribute];
myEntityRow.largeAttribute = largeData;
[myRowsMutableArray removeObjectAtIndex:0];
[applicationContext save:&error];
[applicationContext refreshObject:myEntityRow mergeChanges:NO];
[myInnerPool drain];
[largeData release];
}
[myOuterPool drain];
[myRowsMutableArray release];
}
- (UIImageView *) myMethodUsingParameter : (NSString *) link {
UIImageView * toBeReturned = nil;
NSURL *pdfURL = [NSURL fileURLWithPath:link];
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1);
CGRect pageRect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
UIGraphicsBeginImageContext(pageRect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0);
CGContextFillRect(context,pageRect);
CGContextSaveGState(context);
CGContextTranslateCTM(context, 0.0, pageRect.size.height);
CGContextScaleCTM(context, 1, - 1);
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
CGContextSetRenderingIntent(context, kCGRenderingIntentDefault);
CGContextDrawPDFPage(context, page);
CGContextRestoreGState(context);
UIImage *imageToBeReturned = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CFRelease(pdf);
toBeReturned = [[UIImageView alloc] initWithImage:imageToBeReturned];
UIGraphicsEndImageContext();
return toBeReturned;
}
-
请注意
- 可变数组是作为一种(显然无用的)策略引入的 尽快释放对象
- 已添加池作为同一策略的一部分
- 关于插值质量的声明是唯一需要改进的声明 情况(比如说,移动崩溃 向前一点)
- 在从 6 到 10 的周期范围内为托管对象保留计数 (?)我知道 rc 不是有价值的 信息,但我还是做了一个测试 我发现我可以发送 多个发布消息到托管 强制应用程序执行之前的对象 为此崩溃。但重点是 我不应该发布 我不拥有的对象,是吗? ....
- 设置请求的实体也有一些 双向关系 其他实体,但仍然,这是 相关吗?
谢谢。
【问题讨论】:
-
为什么要返回并存储 UIImageView 而不是图像?
标签: iphone ipad core-data memory-management loops