代码之家  ›  专栏  ›  技术社区  ›  Duck

iphone-主线程冻结半秒…为什么?

  •  0
  • Duck  · 技术社区  · 14 年前

    我有一个应用程序,是在石英背景画线。当用户在屏幕上移动手指时,应用程序开始绘图。

    当上下文被保存到这里时,我会在移动时这样做

    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 回复  |  直到 14 年前
        1
  •  1
  •   Steve McFarlin    14 年前

    你试过:

     performSelector:onThread:withObject:waitUntilDone:
    

    waitUntilDone设置为NO。

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

    如果您尝试这样做,我相信您需要将autorelease池放入函数中,因为它将作为线程的入口和出口。

        2
  •  1
  •   bbum    14 年前

    首先,一个名为like的方法 saveTempImage:: 是要气馁的。成功 saveTempImage:fileName: 或者别的什么。

    然而,猜测通常是分析性能问题的一种无效方法。使用提供的工具。CPU采样器可以告诉你到底发生了什么。

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