iphone - 主线冻结了半秒......为什么?

时间:2010-08-05 21:47:26

标签: iphone ipad

我有一个应用程序,它在石英上下文中绘制线条。当用户在屏幕上移动手指时,应用程序开始绘制。

当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();

}

问题是:一旦用户开始移动,新线程就会被触发,但即使这个新线程具有低优先级,主线程仍然会冻结大约半秒(可能是在保存文件时)。

为什么?

我该如何解决这个问题?

感谢。

2 个答案:

答案 0 :(得分:1)

首先,不鼓励使用名为saveTempImage::的方法。将其设为saveTempImage:fileName:或其他内容。

你的猜测可能很好;保存文件可能是暂停的来源。也可能是渲染本身,如果复杂,但看起来不像。

但是,猜测通常是分析性能问题的非生产性方法。使用提供的工具。 CPU Sampler仪器可以告诉您实际情况。

修复?首先确认问题。如果它是文件I / O,则将其从主线程移开(我没有查看UIImage的文档以了解它是否在这样的上下文中是线程安全的。)

答案 1 :(得分:1)

你试过了吗?

 performSelector:onThread:withObject:waitUntilDone:

将waitUntilDone设置为NO。

如果我记得在主线程上正确执行选择器,则总是在应用程序的主运行循环中处理选择器。我错了。我一直在使用GCD一段时间了。

如果你试试这个,我相信你需要把自动释放池放到函数中,因为它将作为线程的入口和出口点。