你好,我是iPhone开发的新手,所以我可能做错了。我想连续转换一个图像3次,但当我这样做时,它会锁定iphone,直到它完成所有3次转换。我有函数之间的步骤,但他们不会火,直到最后一个图像转换火。如果您阅读下面的代码注释,这就更有意义了。
我的问题是
-
是否有更快的方法来转换图像?2. 我如何阻止它锁定,以便它按顺序触发代码,图像转换之间的函数内联着火?
- (IBAction)ColorFun1 { // // ANY CODE IN THIS location will not fire until 3rd convert is finished // // Image to convert UIImage *originalImage = imageView.image; // 1st Convert CGColorSpaceRef colorSapce = CGColorSpaceCreateDeviceGray(); CGContextRef context = CGBitmapContextCreate(nil, originalImage.size.width, originalImage.size.height, 8, originalImage.size.width, colorSapce, kCGImageAlphaNone); CGContextSetInterpolationQuality(context, kCGInterpolationHigh); CGContextSetShouldAntialias(context, NO); CGContextDrawImage(context, CGRectMake(0, 0, originalImage.size.width, originalImage.size.height), [originalImage CGImage]); CGImageRef bwImage = CGBitmapContextCreateImage(context); // CGContextRelease(context); CGColorSpaceRelease(colorSapce); // UIImage *resultImageBW = [UIImage imageWithCGImage:bwImage]; // This is result B/W image. [fxImage2View setImage:resultImageBW]; // // ANY CODE IN THIS location will not fire until 3rd convert is finished // // // // 2nd Convert // UIGraphicsBeginImageContext(resultImageBW.size); CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeCopy); [resultImageBW drawInRect:CGRectMake(0, 0, resultImageBW.size.width, resultImageBW.size.height)]; CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeDifference); CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(),[UIColor grayColor].CGColor); CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, resultImageBW.size.width, resultImageBW.size.height)); UIImage *returnImage = UIGraphicsGetImageFromCurrentImageContext(); [fxImage1View setImage:returnImage]; UIGraphicsEndImageContext(); // // // // ANY CODE IN THIS location will not fire until 3rd convert is finished // // // // 3rd Convert // UIGraphicsBeginImageContext(resultImageBW.size); CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeCopy); [resultImageBW drawInRect:CGRectMake(0, 0, resultImageBW.size.width, resultImageBW.size.height)]; CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeSoftLight); CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(),[UIColor colorWithRed:40 green:20 blue:0 alpha:1].CGColor); CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, resultImageBW.size.width, resultImageBW.size.height)); returnImage = UIGraphicsGetImageFromCurrentImageContext(); [fxImage3View setImage:returnImage]; UIGraphicsEndImageContext(); CGImageRelease(bwImage); }
您需要像sergio所说的那样将控制权转移回运行循环。我建议你去查查中央调度中心。来自维基百科
Grand Central Dispatch仍然在底层使用线程,但是将它们从程序员那里抽象出来,程序员不需要关心那么多的细节。GCD中的任务是轻量级的,可以创建和排队;苹果公司表示,在GCD中排队一个工作单元需要15条指令,而创建一个传统线程很容易需要几百条指令
应该不难找到如何实现它的教程。你甚至可以考虑斯坦福大学的开发讲座。这个是关于性能的;线程。我认为与你相关的部分从33:36开始
我认为你的问题取决于这样一个事实,即因为你正在做一堆处理而没有将控制返回到主循环,你的UI在两者之间没有更新。
一种可能性是定义三个方法,每个方法进行一次图像转换(这也有助于代码的可读性)。然后你可以调用它们,在调用之间流控制回到主循环和UI更新的方式。
作为一个例子,如果你的3个方法是convertImage1
, convertImage2
和convertImage3
,你可以这样做:
[self performSelector:@selector(convertImage1) withObject:nil afterDelay:0];
[self performSelector:@selector(convertImage2) withObject:nil afterDelay:0];
[self performSelector:@selector(convertImage3) withObject:nil afterDelay:0];
如果您使用Grand Central Dispatch dispatch_async
方法来调度调用,则可以以更简洁的方式获得相同的效果:
dispatch_async(dispatch_get_main_queue(), ^{ [self convertImage1]; });
dispatch_async(dispatch_get_main_queue(), ^{ [self convertImage2]; });
dispatch_async(dispatch_get_main_queue(), ^{ [self convertImage3]; });
这里有很多你可以调整的设计变量;这只是一个给你一个概念的例子。