Ale*_*dro 16 memory objective-c uikit cgcontext ios
我正在尝试在PDF中创建页面的预览图像但我在内存释放方面遇到了一些问题.
我写了一个循环问题的简单测试算法, 应用程序在第40次迭代附近崩溃:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent:@"myPdf.pdf"];
CFURLRef url = CFURLCreateWithFileSystemPath( NULL, (CFStringRef)pdfPath, kCFURLPOSIXPathStyle, NO );
CGPDFDocumentRef myPdf = CGPDFDocumentCreateWithURL( url );
CFRelease (url);
CGPDFPageRef page = CGPDFDocumentGetPage( myPdf, 1 );
int i=0;
while(i < 1000){
UIGraphicsBeginImageContext(CGSizeMake(768,1024));
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0);
CGContextFillRect(context,CGRectMake(0, 0, 768, 1024));
CGContextSaveGState(context);
CGContextTranslateCTM(context, 0.0, 1024);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextDrawPDFPage(context, page);
CGContextRestoreGState(context);
// --------------------------
// The problem is here (without this line the application doesn't crash)
UIImageView *backgroundImageView1 = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()];
// --------------------------
UIGraphicsEndImageContext();
[backgroundImageView1 release];
NSLog(@"Loop: %d", i++);
}
CGPDFDocumentRelease(myPdf);
Run Code Online (Sandbox Code Playgroud)
上述线路似乎会产生内存泄漏,但是,仪器不会出现内存问题;
我可以摆脱这种错误吗?有人可以用哪种方式解释我?是否有其他方式来显示pdf的预览?
UPDATE
我认为问题不是该UIImage
方法创建UIGraphicsGetImageFromCurrentImageContext()
的版本,而是UIImageView
使用此自动释放图像创建的版本.
我将代码行分为三个步骤:
UIImage *myImage = UIGraphicsGetImageFromCurrentImageContext();
UIImageView *myImageView = [[UIImageView alloc] init];
[myImageView setImage: myImage]; // Memory Leak
Run Code Online (Sandbox Code Playgroud)
第一行和第二行不会造成内存泄漏,所以我认为方法UIGraphicsGetImageFromCurrentImageContext不是问题.
我也尝试如下但问题仍然存在:
UIImageView *myImageView = [[UIImageView alloc] initWithImage:myImage];
Run Code Online (Sandbox Code Playgroud)
我认为UIImageView的发布中存在内存泄漏,其中包含具有autorelease属性的UIImage.
我尝试编写我的对象UIImageView继承UIView,如此线程中所述.
这个解决方案有效,但不是很优雅,这是一个解决方法,我宁愿使用对象UIImageView解决内存问题.
Ole*_*ann 26
问题是这样的:
UIGraphicsGetImageFromCurrentImageContext()
Run Code Online (Sandbox Code Playgroud)
返回自动释放UIImage
.自动释放池保留此图像,直到您的代码将控制权返回到runloop,这是您很长时间没有做到的.要解决此问题,您必须在循环的每次迭代(或每几次迭代)中创建并排空新的自动释放池while
.
Cha*_*esA 14
我知道这是一个古老的问题,但我刚刚将头撞在墙上几个小时.在我的应用程序反复调用
UIImage *image = UIGraphicsGetImageFromCurrentImageContext()
Run Code Online (Sandbox Code Playgroud)
尽管我调用了image = nil,但是在循环中确实保留了内存; 不知道应用程序在释放之前会持续多长时间来保持内存,但它确实足够长,以便我的应用程序获得内存警告然后崩溃.
我设法通过包装调用/使用@autoreleasepool中的UIGraphicsGetImageFromCurrentImageContext()的图像来解决它.所以我有:
@autoreleasepool {
UIImage *image = [self imageWithView:_outputImageView]; //create the image
[movie addImage:image frameNum:i fps:kFramesPerSec]; //use the image as a frame in movie
image = nil;
}
Run Code Online (Sandbox Code Playgroud)
希望可能对某人有所帮助.
为了将来参考,这是我为解决此问题所做的工作(在 Swift 4 中测试)。
我正在为从互联网下载的每个新图像(在实用程序队列中)调用下面的函数。在实现自动释放池之前,它会在处理大约 100 个之后崩溃。
为简单起见,在 resizeImage 函数中,除了 autoreleasepool 和泄漏的部分之外,我删除了所需的代码。
private func resizeImage(image: UIImage, toHeight: CGFloat) -> UIImage {
return autoreleasepool { () -> UIImage in
[...]
let newImage = UIGraphicsGetImageFromCurrentImageContext() //Leaked
UIGraphicsEndImageContext()
return newImage!
}
}
Run Code Online (Sandbox Code Playgroud)
我希望这有帮助!
这段代码是在主线程上运行的吗?UIGraphicsGetImageFromCurrentImageContext(链接)的文档表明它必须以这种方式运行。
归档时间: |
|
查看次数: |
26595 次 |
最近记录: |