【发布时间】:2014-01-13 19:26:28
【问题描述】:
我有一个需要截取屏幕截图并将其保存为文件的应用程序。我使用的是 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;
}
在非视网膜 iPad 上运行此程序时,UIImage 对象的创建使内存增加了 1 MB,NSData 又增加了 4 MB,当我多次运行时,此内存为没有发布!在视网膜 iPad 上,每次调用 saveNow: 的费用约为 17 MB,这会导致设备在运行几次后耗尽内存。
一些额外的信息。我在一个循环中运行此代码,该循环总共迭代了 300 多次(每次迭代都会对视图进行小的更改,我需要每个屏幕截图以供查看)。如果我减少迭代次数以使设备不会耗尽内存,我可以看到一旦包含循环的方法返回,内存就会被释放。然而,这并不理想,我希望将大量内存代码放到它自己的函数中(saveNow:)应该会有所改进,但事实并非如此。如何强制这些对象在不需要时立即释放,而不是等待父方法返回?希望不必在整个项目上禁用 ARC。
编辑:我尝试像这样使用@autoreleasepool:
@autoreleasepool {
[self saveNow:filePath];
}
结果更好但并不完美。当块完成时,它会释放大约 4 MB 的内存,但在容器方法返回之前,还有 1 MB 的内存仍然被卡住。所以这是一个 80% 的改进(是的!)但我的目标是 100% :) 我会阅读更多关于 @autoreleasepool 的信息,因为我以前没有使用过它。
【问题讨论】:
-
尝试将你的 saveNow: 方法封装在 @autoreleasepool 中?
-
你是在主线程还是后台线程中运行
saveNow? -
你能发布你的循环代码吗?
-
我在主线程上运行它。循环非常大而且嵌套,我将看看发布它的简洁版本是否有意义。
标签: ios objective-c memory-leaks uiimage nsdata