iOS Objective-C相当于Win32 PeekMessage / Translate / Dispatch

时间:2017-02-18 14:17:58

标签: ios objective-c dispatch

在Windows中,可以在代码中运行事件..

//PeekMessage loop example
while (WM_QUIT != uMsg.message)
{
     while (PeekMessage (&uMsg, NULL, 0, 0, PM_REMOVE) > 0) //Or use an if statement
     {
          TranslateMessage (&uMsg);
          DispatchMessage (&uMsg);
     }
}

在Objective-C for iOS中,是否有一种方法可以间歇性地运行事件,例如for-loop?

我有一些深度嵌套的代码,需要一些时间来运行,我希望它能间歇性地更新进度。重新设计深层嵌套代码实际上不是一个选项,它可以在其他操作系统上运行。

3 个答案:

答案 0 :(得分:1)

所以,你基本上想要运行一个长任务并相应地更新进度。这可以通过GCD中的NSOperationQueueObjective-C来完成。下面的代码为您提供了一个示例。

这里我将使用一个以块作为输入的函数。该函数包含异步代码。

typedef void(^ProgressBlock)(CGFloat progress); // defined block

- (void)executeTaskWithProgress:(ProgressBlock)progress; // defined function

您可以通过以下两种方式异步运行任务:

  1. 使用GCD

    - (void)executeTaskWithProgress:(ProgressBlock)progress {
    
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
                  // your long running task
    
                  // the below line is for updating progress
                  dispatch_async(dispatch_get_main_queue(), ^{
                      progress(20.0);
                  });
            });
     }
    
  2. 使用NSOperation

    - (void)executeTaskWithProgress:(ProgressBlock)progress {
    
            NSOperationQueue *executionQueue = [[NSOperationQueue alloc] init];
            NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
               // your long running task
    
               // the below line is for updating progress
               [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                   progress(20.0);
               }];
            }];
    
            [executionQueue addOperation:operation];
     }
    
  3. 您可以通过以下方式调用该函数:

    [self executeTaskWithProgress:^(CGFloat progress) {
        [self.myLabel setText:[NSString stringWithFormat:@"%f completed", progress]];
        // myLabel is an UILabel object
    }];
    

    有关使用GCD中的Objective-C进行异步编程的更多详细信息,建议您查看以下tutorial。随意提出任何疑问

答案 1 :(得分:0)

您可以在控制器中使用NSTimer进行以下操作:

- (void)viewDidLoad {
    [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(timerCalled) userInfo:nil repeats:YES];
}

-(void)timerCalled
{
    NSLog(@"timer called");
}

答案 2 :(得分:0)

我不熟悉现代Windows异步编程技术或PeekMessage功能。你应该解释一般CS术语的作用。

听起来这是一种在执行耗时任务时响应系统事件的方法。

iOS采用略有不同的方法。它是一个运行"事件循环的多线程操作系统"在主线程上。每次通过事件循环,系统都会检查需要响应的事件(触摸事件,通知,WiFi或蜂窝网络中的数据,屏幕更新等)并处理它们。

您需要编写在主线程上运行的代码来执行简短任务以响应用户操作或系统事件,然后返回。您不应该在主线程上执行耗时的任务。

有一个名为Grand Central Dispatch的框架,它为后台线程(或主线程上的运行任务)提供高级支持。你也有NSOperationQueues,它支持管理任务的队列。在主线程或后台同时或并行运行。

这两个操作系统使用不同的范例来处理事件和并发,并且可能没有简单的"使用此功能而不是"替换你目前的做事方式。

您可能应该重构长时间运行的任务以在后台线程上运行,然后在您想要更新用户界面时将消息发送到主线程。