代码非常简单,它必须从设置文件加载所有现有图像引用,将它们缩放到250x250并用另一个名称保存它们。
问题是在设备上(在iPhone 3g和iPad上测试)它会在一段时间后因内存警告而崩溃。在模拟器上,它的工作非常完美。
我有一个UIViewController,它在ViewDidAppear上有这段代码:
ThreadPool.QueueUserWorkItem( delegate{
make_thumbs();
});
make_thumbs函数是:
void make_thumbs()
{
using( var ns = new NSAutoreleasePool() )
{
foreach( var c in Settings.Instance.Categories )
{
for( var i = 0; i < c.Pictures.Count; i++ )
{
//this is the existing bundled image path
string path = c.Pictures[i].PicturePath;
string folder = Environment.GetFolderPath( Environment.SpecialFolder.Personal );
//this is the destination image file name
string filename = Path.Combine( folder, c.Name + i + ".png");
if( !File.Exists( filename ) )
{
NSError err;
using(UIImage img = UIImage.FromFile( path ).Scale( 250,250 ))
{
img.AsPNG().Save( filename, true, out err );
}
}
}
}
}
}
答案 0 :(得分:4)
你需要扩展我的建议(来自mailing-list),以便在你的循环中实现IDisposable
的所有内容(因为它可以更快地分配内存) GC将能够收集它。)
就像@Rolf所说,在评论中,img.AsPNG()
会返回NSData
来实现IDisposable
。
同时调用Scale
方法也会返回新的UIImage
。
using(UIImage img = UIImage.FromFile( path )) {
using (var scaled_img = img.Scale( 250,250 )) {
using (var data = img.AsPNG ()) {
data.Save( filename, true, out err );
}
}
}
这应该涵盖这个块,即确保尽快回收所有内存,这应该有助于你的设备(不是很多内存可用)。
答案 1 :(得分:2)
Thx @poupou,这几乎是你的答案,有点完成:我不得不把 在for循环中使用(var ns = new NSAutoreleasePool())。所以我的代码现在就像这样,它正在运行:
if( !File.Exists( filename ) )
{
using( var ns = new NSAutoreleasePool() )
{
NSError err;
using(UIImage img = UIImage.FromFile( path )) {
using (var scaled_img = img.Scale( 250,250 ))
{
//i also add a reflection effect
using( var reflected_img = scaled_img.AddImageReflection( 0.6f ) )
{
using (var data = reflected_img.AsPNG ())
{
data.Save( filename, true, out err );
}
}
}
}
}
}