代码之家  ›  专栏  ›  技术社区  ›  Rits

块而不是PerformSelector:WithObject:AfterDelay:[重复]

  •  87
  • Rits  · 技术社区  · 14 年前

    我经常想在未来几微秒内执行一些代码。现在,我这样解决它:

    - (void)someMethod
    {
        // some code
    }
    

    而这:

    [self performSelector:@selector(someMethod) withObject:nil afterDelay:0.1];
    

    它有效,但我每次都必须创建一个新方法。是否可以使用块而不是这个?基本上,我在寻找一种方法,比如:

    [self performBlock:^{
        // some code
    } afterDelay:0.1];
    

    那对我很有用。

    6 回复  |  直到 11 年前
        1
  •  106
  •   PeyloW    14 年前

    没有内置的方法可以做到这一点,但是通过一个类别添加并不太糟糕:

    @implementation NSObject (PerformBlockAfterDelay)
    
    - (void)performBlock:(void (^)(void))block 
              afterDelay:(NSTimeInterval)delay 
    {
        block = [[block copy] autorelease];
        [self performSelector:@selector(fireBlockAfterDelay:) 
                   withObject:block 
                   afterDelay:delay];
    }
    
    - (void)fireBlockAfterDelay:(void (^)(void))block {
        block();
    }
    
    @end
    

    学分 Mike Ash 用于基本实现。

        2
  •  41
  •   Nick Moore Wain    14 年前

    下面是一个基于GCD的简单技术,我正在使用:

    void RunBlockAfterDelay(NSTimeInterval delay, void (^block)(void))
    {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC*delay),
          dispatch_get_current_queue(), block);
    }
    

    我不是GCD专家,我对这个解决方案的评论很感兴趣。

        3
  •  22
  •   ninjaneer    13 年前

    另一种方法(可能是因为许多原因而做这件事的最糟糕的方法)是:

    [UIView animateWithDuration:0.0 delay:5.0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
    } completion:^(BOOL finished) {
        //do stuff here
    }];
    
        4
  •  16
  •   Greg Combs    14 年前

    如果您特别需要更长的延迟,上面的解决方案就可以了。我成功地使用了@nick的方法。

    但是,如果只希望块在主循环的下一个迭代期间运行,则可以使用以下方法进一步修剪它:

    [[NSOperationQueue mainQueue] addOperationWithBlock:aBlock];
    

    这类似于使用PerformSelector:后延迟为0.0f

        5
  •  11
  •   Despotovic    11 年前

    我用了类似的代码:

    double delayInSeconds = 0.2f;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
          //whatever you wanted to do here...  
        });
    
        6
  •  1
  •   Duane Fields    13 年前

    这里有一个很好的、完整的类别来处理这种情况:

    https://gist.github.com/955123

    推荐文章