【问题标题】:method not called with dispatch_async and repeating NSTimer未使用 dispatch_async 调用并重复 NSTimer 的方法
【发布时间】:2013-11-28 13:15:48
【问题描述】:

我正在开发一个应用程序,我想使用dispatch_async 在单独的队列中调用方法。我想在一定的时间间隔后重复调用该方法。但是该方法没有被调用。

我不知道怎么了。这是我的代码:

dispatch_async( NotificationQueue, ^{

        NSLog(@"inside queue");
        timer = [NSTimer scheduledTimerWithTimeInterval: 20.0
                                                 target: self
                                               selector: @selector(gettingNotification)
                                               userInfo: nil
                                                repeats: YES];

        dispatch_async( dispatch_get_main_queue(), ^{
            // Add code here to update the UI/send notifications based on the
            // results of the background processing

        });
    });

-(void)gettingNotification {
    NSLog(@"calling method ");
}

【问题讨论】:

    标签: ios iphone grand-central-dispatch nstimer


    【解决方案1】:

    如果您希望在 dispatch_queue_t 上调用重复计时器,请使用 dispatch_source_createDISPATCH_SOURCE_TYPE_TIMER

    dispatch_queue_t  queue = dispatch_queue_create("com.firm.app.timer", 0);
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), 20ull * NSEC_PER_SEC, 1ull * NSEC_PER_SEC);
    
    dispatch_source_set_event_handler(timer, ^{
    
        // stuff performed on background queue goes here
    
        NSLog(@"done on custom background queue");
    
        // if you need to also do any UI updates, synchronize model updates,
        // or the like, dispatch that back to the main queue:
    
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"done on main queue");
        });
    });
    
    dispatch_resume(timer);
    

    这将创建一个每 20 秒运行一次的计时器(dispatch_source_set_timer 的第三个参数),还有一秒的余量(dispatch_source_set_timer 的第四个参数)。

    要取消此计时器,请使用dispatch_source_cancel

    dispatch_source_cancel(timer);
    

    【讨论】:

    • 只是将上述内容添加到视图中并在 vc 中加载并不会生成任何控制台输出,缺少什么?
    • @DavidKarlsson timer 变量实际上必须是类属性(或 ivar)。与NSTiner 不同,如果超出范围,调度计时器将被取消并释放。
    【解决方案2】:

    试试这个代码

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    
        dispatch_async( dispatch_get_main_queue(), ^{
    
            timer = [NSTimer scheduledTimerWithTimeInterval: 1.0 target: self
                                                   selector: @selector(gettingNotification) userInfo: nil repeats: YES];
            // Add code here to update the UI/send notifications based on the
            // results of the background processing
    
        });
    });
    
    -(void)gettingNotification {
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
             //background task here
        dispatch_async( dispatch_get_main_queue(), ^{
            // update UI here
            );
    });
    }
    

    【讨论】:

    • 这也是正确的,尽管调度源可能是更直接的机制。但是,可以简化此答案,因为将计时器的创建分派到后台队列然后再分派到主队列是没有意义的。只需在主队列中创建重复计时器,无需两个嵌套调度。不过,+1。
    【解决方案3】:
    int parameter1 = 12;
    float parameter2 = 144.1;
    
    // Delay execution of my block for 10 seconds.
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
        NSLog(@"parameter1: %d parameter2: %f", parameter1, parameter2);
    });
    

    寻找更多

    How do you trigger a block after a delay, like -performSelector:withObject:afterDelay:?

    【讨论】:

    • 但是我将如何重复调用该方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-14
    • 2017-05-06
    • 1970-01-01
    • 2018-12-03
    • 1970-01-01
    相关资源
    最近更新 更多