UI不更新,而某些函数需要时间来执行? [英] UI is not updating while some function takes time to execution?

查看:95
本文介绍了UI不更新,而某些函数需要时间来执行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做一些图像处理,这也显示了加载。

  for(ALAsset * assets in asset){
weakSelf.HUD.labelText = [NSString stringWithFormat:@%d /%d,count,assets.coun
weakSelf.HUD.progress =(CGFloat)count / assets.count;
[objDoc setImageProcess:asset];
count ++;
}

HUD并未更新其值。如果我把延迟,然后显示。这里 setImageProcess 需要时间来处理。

解决方案

UI更新发生在iOS和Mac OS中的主线程。如果您在后台线程上运行耗时的代码,则可以将消息发送到主线程以更新UI,并且完美地工作。



如果您正在运行你在主线程上耗费时间的代码,UI变化得到积累,并且只在你的应用程序返回并访问事件循环时才呈现在屏幕上。

所以,if你有一个循环,执行一堆耗时的任务,直到整个循环完成才会返回,它不起作用,因为UI更新不会在你返回之前发生。



您需要重构代码才能在迭代之间返回。就像这样:

创建一个实例变量assetCount:

  @接口myClass:UIViewController; 
{
NSInteger assetIndex;
}
@end。

然后

   - (void)viewDidLoad; 
{
assetIndex = 0;
[self processAssets];
}

- (void)processAssets;
{
if(assetIndex> = assets.count)
return;
ALAsset * asset = assets [assetIndex];
weakSelf.HUD.labelText = [NSString stringWithFormat:@%d /%d,count,assets.coun
weakSelf.HUD.progress =(CGFloat)count / assets.count;
[objDoc setImageProcess:asset];
assetIndex ++;
count ++;

//下列方法调用队列中的方法调用
//,以便您的应用下次访问事件循环。 (加上一个可选的延迟)
[self performSelector:processAssets
withObject:nil
afterDelay:0];
}

上述方法处理1资产,然后将延迟呼叫排队等待其自身。即使延迟值为0,它仍然可以解决您的问题。这是因为performSelector:withObject:afterDelay:方法总是立即返回,并将方法调用排队等待下一个事件循环。在接下来的事件循环中,系统会像更新屏幕一样进行清理,然后检查像这样的未决呼叫。如果有延迟,它将启动一个计时器。如果没有,它会触发你的方法调用。



你在发布的代码中有一个变量计数,它可以用作数组索引。我添加了一个新的实例变量assetIndex来跟踪当前的数组索引。您的代码也使用术语weakSelf,暗示此代码正在从块中执行。这可能是一种更清晰的方式来处理,但您需要提供更多信息。


I am doing some image processing and with this also showing the loading. Problem is that loading is not updating.

for (ALAsset *asset in assets) {
  weakSelf.HUD.labelText = [NSString stringWithFormat:@"%d/%d",count,assets.coun
  weakSelf.HUD.progress=(CGFloat)count/assets.count;
  [objDoc setImageProcess:asset];
  count++;
}

Here the HUD is not updating its value. If I put the delay then its showing. Here setImageProcess takes time while processing.

解决方案

UI updates take place on the main thread in iOS and Mac OS. If you have time-consuming code that runs on a background thread, you can send messages to the main thread to update the UI and it works perfectly.

If you are running your time-consuming code on the main thread, UI changes get accumulated, and only get rendered to the screen when your app returns and visits the event loop.

So, if you have a loop that does a bunch of time-consuming tasks and doesn't return until the whole loop is finished, it doesn't work because the UI updates don't take place until you return.

You need to refactor your code to return between iterations. Something like this:

Create an instance variable assetCount:

@interface myClass: UIViewController;
{
  NSInteger assetIndex;
}
@end.

Then

-(void) viewDidLoad;
{
  assetIndex = 0;
  [self processAssets];
}

- (void) processAssets;
{
  if (assetIndex >= assets.count)
    return;
  ALAsset *asset = assets[assetIndex];
  weakSelf.HUD.labelText = [NSString stringWithFormat:@"%d/%d",count,assets.coun
  weakSelf.HUD.progress=(CGFloat)count/assets.count;
  [objDoc setImageProcess:asset];
  assetIndex++;
  count++;

  //The following method call queues up a method call 
  //for the next time your app visits the event loop. (plus an optional delay)
  [self performsSelector: processAssets 
    withObject: nil
    afterDelay: 0];
}

The method above processes 1 asset, then queues a delayed call to itself. Even though the delay value is 0 it still fixes your problem. That's because the performSelector:withObject:afterDelay: method always returns immediately, and queues up the method call for the next pass through the event loop. In the next pass through the event loop, the system does housekeeping like updating the screen, then checks for pending calls like this one. If there is a delay it will start a timer. If not, it will trigger your method call.

You have a variable count in the code you posted that might work as an array index. I added a new instance variable assetIndex to track the current array index. Your code also uses the term weakSelf, suggesting that this code is being executed from a block. It might be that there is a cleaner way to handle this, but you would need to provide more information.

这篇关于UI不更新,而某些函数需要时间来执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆