我有一个需要截屏并保存为文件的应用程序。因为我使用了ARC,所以不需要手动释放变量,但似乎我的代码存在严重的内存泄漏问题。
这是我正在运行的代码:
- (BOOL) saveNow:(NSString *)filePath {
UIImage *image = [self.view getImage];
NSData *imageData = UIImagePNGRepresentation(image);
return [imageData writeToFile:filePath atomically:YES];
}
这里的getImage
是UIView类别中的一个方法:
- (UIImage *)getImage {
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, [[UIScreen mainScreen]scale]);
[[self layer] renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return viewImage;
}
在非retina版本的iPad上运行此代码时,每次创建UIImage对象会额外占用1MB内存,NSData会再占用4MB内存,而且由于此代码需要多次运行,这些内存并不会被释放。在retina版本的iPad上,每次调用saveNow:方法大约需要消耗17MB的内存,容易导致设备在几次运行后内存耗尽。
额外说明:我在一个循环中运行该代码,总共迭代了300多次(每次迭代都对视图进行微小更改,需要对每个视图截屏以供审核)。如果我减少迭代次数以避免设备内存耗尽,那么当包含循环的方法返回后,我可以看到内存已被释放。但是,这不是理想的解决方案,我希望将内存密集型的代码移到自己的函数saveNow:中应该能够改善内存使用情况,但实际效果不佳。有没有办法在这些对象不再需要时立即释放它们,而不是等待父方法返回?最好不要禁用整个项目的ARC功能。
编辑:我尝试使用autoreleasepool,如下所示:
@autoreleasepool {
[self saveNow:filePath];
}
结果比以前好了,但并不完美。当块完成时,它会释放约4 MB的内存,但另外1 MB仍然会被卡住,直到容器方法返回。所以,这是一个80%的改进(耶!),但我目标是100% :) 我会多读一些关于@autoreleasepool
的信息,因为我以前没有使用过。
saveNow
? - Putz1103