我有一个应用程序,它在石英上下文中绘制线条。当用户在屏幕上移动手指时,应用程序开始绘制。
当TouchesMoved被触发时,我将石英上下文保存到PNG文件(我知道保存文件很慢...我试图对内存这样做,但应用程序内存使用率暴涨,所以,我试图做到磁盘)。
当上下文保存到此时,我会在移动触摸时执行此操作
if (firstMove) // first movement after touchesbegan
[NSThread detachNewThreadSelector:@selector(newThreadUNDO)
toTarget:self
withObject:nil];
firstMove = NO
}
然后我
- (void) newThreadUNDO {
NSAutoreleasePool* p = [[NSAutoreleasePool alloc] init];
[NSThread setThreadPriority:0.1];
[NSThread sleepForTimeInterval:0.0];
[self performSelectorOnMainThread:@selector(copyUNDOcontext) withObject:nil waitUntilDone:NO];
[p release];
}
和
- (void) copyUNDOcontext {
CGFloat w = board.image.size.width;
CGFloat h = board.image.size.height;
CGRect superRect = CGRectMake(0,0, w, h);
CGSize size = CGSizeMake(w, h);
UIGraphicsBeginImageContext(size);
CGContextRef new = UIGraphicsGetCurrentContext();
// lineLayer is the layer context I need to save
CGContextDrawLayerInRect(new, superRect, lineLayer);
UIImage *imagem = UIGraphicsGetImageFromCurrentImageContext();
[self saveTempImage:imagem :@"UNDO.png"];
UIGraphicsEndImageContext();
}
问题是:一旦用户开始移动,新线程就会被触发,但即使这个新线程具有低优先级,主线程仍然会冻结大约半秒(可能是在保存文件时)。
为什么?
我该如何解决这个问题?
感谢。
答案 0 :(得分:1)
首先,不鼓励使用名为saveTempImage::
的方法。将其设为saveTempImage:fileName:
或其他内容。
你的猜测可能很好;保存文件可能是暂停的来源。也可能是渲染本身,如果复杂,但看起来不像。
但是,猜测通常是分析性能问题的非生产性方法。使用提供的工具。 CPU Sampler仪器可以告诉您实际情况。
修复?首先确认问题。如果它是文件I / O,则将其从主线程移开(我没有查看UIImage
的文档以了解它是否在这样的上下文中是线程安全的。)
答案 1 :(得分:1)
你试过了吗?
performSelector:onThread:withObject:waitUntilDone:
将waitUntilDone设置为NO。
如果我记得在主线程上正确执行选择器,则总是在应用程序的主运行循环中处理选择器。我错了。我一直在使用GCD一段时间了。
如果你试试这个,我相信你需要把自动释放池放到函数中,因为它将作为线程的入口和出口点。