简体   繁体   English

异步 function 执行?

[英]Asynchronous function execution?

in my iOS app I do the following.在我的 iOS 应用程序中,我执行以下操作。

viewDidAppear(){

   // Load a spinner in a view on the top
   [DSBezelActivityView newActivityViewForView:self.view]; 
   // Execute code that require 3 seconds
   ...
   // Stop the spinner
   [DSBezelActivityView removeViewAnimated:YES];
}

The problem is that the spinner doesn't appear, because the the cpu is working hard (something similar).问题是微调器没有出现,因为 cpu 正在努力工作(类似的东西)。 It's like that the code betweek the start and stop has precedence on the rendering of the view.就像代码在开始和停止时优先于视图的渲染一样。

I would love to find a way to show effectively the start of the spinner, without using a timer to delay the code execution.我很想找到一种方法来有效地显示微调器的启动,而不使用计时器来延迟代码执行。

Thanks谢谢

If you have a method like如果您有类似的方法

-(void) showSpinner:(UIView*)view {
    dispatch_async(dispatch_get_main_queue(), ^{
        [DSBezelActivityView newActivityViewForView:view];
    });
}

there are several ways to call it from a different thread.有几种方法可以从不同的线程调用它。 Choose one from the following:从以下选项中选择一项:

[NSThread detachNewThreadSelector:@selector(showSpinner:) toTarget:self withObject:self.view];
// or 
[self performSelectorInBackground:@selector(showSpinner:) withObject:self.view];
// or 
NSInvocationOperation *invOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(showSpinner:) object:self.view];
NSOperationQueue *opQueue = [[NSOperationQueue alloc] init];
[opQueue addOperation:invOperation];
// or 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [self showSpinner:self.view];
});

Alt + click for details. Alt + 单击以获取详细信息。

Move code between start and stop activity indicator into separate thread because it's blocking main thread.将开始和停止活动指示器之间的代码移动到单独的线程中,因为它阻塞了主线程。 That's why activity indicator is not showing.这就是没有显示活动指示器的原因。

Edit: Example编辑: 示例

I agree with the 1st answer with a couple of modifications.我同意第一个答案并进行了一些修改。 I just went through this exact same problem.我刚刚经历了同样的问题。 The problem is that anything graphical is going to automatically move to the background updating when you have code that takes time to get through.问题是,当您的代码需要时间才能通过时,任何图形都会自动移动到后台更新。 Throwing the spinner to the background is what it essantially doing anyway.无论如何,将微调器扔到背景是它本质上所做的事情。 What you want is (sadly) for you main code to run in the background and the spinner to run in the foreground.您想要的是(可悲地)让您的主要代码在后台运行,而微调器在前台运行。 I know this sounds bad, but in some cases allowing your code to run a bit slower to give indication that the app is doing something useful is beneficial to the user.我知道这听起来很糟糕,但在某些情况下,让您的代码运行得慢一点,以表明应用程序正在做一些有用的事情,这对用户是有益的。

In order to get the spinner to work: 1) Take all the code that takes the 3 seconds to run, and put that into a function that is a void function 2) Instantiate your spinner but store it to a variable that is accessible outside your viewDidAppear routine.为了让微调器工作:1)获取所有需要运行 3 秒的代码,并将其放入一个 function 中,它是一个 void function 2)实例化你的微调器,但将其存储到一个可以在你的外部访问的变量中viewDidAppear 例程。 3) Startup a new NSTimer with that runs continuously with an increment of about every quarter second or so. 3) 启动一个新的 NSTimer,它以大约每四分之一秒左右的增量连续运行。 I will define what goes into the routine that gets called every cycle later.我将定义稍后每个循环调用的例程中的内容。 4) Call the routine you created in step 1 using the performSelectorInBackground capability. 4) 使用 performSelectorInBackground 功能调用您在步骤 1 中创建的例程。 This essentially is now going to run your startup (3 seconds worth) in the background which is really the only way to allow the animated spinner to show up and truly animate.这实际上是现在将在后台运行您的启动(价值 3 秒),这实际上是让动画微调器出现并真正动画化的唯一方法。 5) In the routine you created in step 1, add a line of code right at the top that updates a (global to the object) boolean to true, stating that we are in the middle of our main 3 second routine. 5) 在您在步骤 1 中创建的例程中,在顶部添加一行代码,将(对象的全局)boolean 更新为 true,说明我们正处于主 3 秒例程的中间。 6) At the end of the routine defined in step 1 add a line of code setting the same global defined in step 5 to false indicating that our 3 second routine is completed. 6) 在步骤 1 中定义的例程末尾添加一行代码,将步骤 5 中定义的相同全局设置为 false,表示我们的 3 秒例程已完成。 7) In the timer routine, we now want to do something that looks like the following: 7) 在计时器例程中,我们现在想做一些如下所示的事情:

// If busy that start the spinner
if(YES == busy){
    [spinner startAnimating];
}else{
    [spinner stopAnimating];

    // Here we can also stop and deallocate the timer
}

If you need more aid on this subject, I can indeed provide exact code.如果您在这个主题上需要更多帮助,我确实可以提供确切的代码。 Take a look at the example app that I have developed for the Pepperdine News Group.看看我为 Pepperdine News Group 开发的示例应用程序。 When you press a button, the spinner comes up on the top right of the screen.当您按下按钮时,微调器会出现在屏幕的右上角。

http://itunes.apple.com/us/app/pepperdine-graphic-for-iphone/id516343215?mt=8 http://itunes.apple.com/us/app/pepperdine-graphic-for-iphone/id516343215?mt=8

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM