延迟类选择器调用

Posted

技术标签:

【中文标题】延迟类选择器调用【英文标题】:Delayed Class Selector Call 【发布时间】:2014-10-06 19:35:00 【问题描述】:

我正在尝试使用 args 在延迟上异步调用类方法以隐藏 UILabel。本质上,标签应该出现,然后在三秒钟内消失。我正在使用以下内容来完成此操作。

设置显示视图的主要方法

 +(void)queueError:(UILabel*)messageView errorText:(NSString*)errorText
        [messageView setText:errorText];
        messageView.hidden = NO;
        messageView.tag = arc4random_uniform(UINT32_MAX);
        [UIView animateWithDuration:0.3 delay:0.0 options:0 animations:^()
            messageView.alpha = 1.0;
        completion:^(BOOL finished)
            NSArray* args = [NSArray arrayWithObjects:messageView, [NSNumber numberWithInt:messageView.tag ], nil];
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
                [[UBSNavigationUtils class] performSelector:@selector(dequeueErrorTime:) withObject:args afterDelay:3];
            );
        ];
    

延迟三秒后调用的方法

+(void)dequeueErrorTime:(NSArray*)args
    UILabel* messageView = args[0];
    NSInteger tag = [((NSNumber*)args[1]) integerValue];
    if(messageView.tag == tag)
        [[UBSNavigationUtils class] fadeOutError:messageView];
    

但是,我的方法永远不会被调用。

【问题讨论】:

你怎么知道它没有被调用?您是否在检查方法中设置了断点,或者您的 UILabel 没有隐藏?您是否在主线程上执行淡出/隐藏? 【参考方案1】:

您将选择器放在 dispatch_queue 运行循环中(技术上作为计时器),它没有运行。因此,您的方法从未调用过。我认为,如果您尝试调用 [[NSRunLoop currentRunLoop]run]; ,方法将被调用。

来自苹果关于performSelector:afterDelay:的讨论 当计时器触发时,线程尝试将消息从运行循环中取出并执行选择器。如果 run loop 正在运行并且处于默认模式,则成功;否则,计时器会一直等待,直到运行循环处于默认模式。

【讨论】:

【参考方案2】:

不要使用dispatch_async,而是考虑dispatch_after

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
  [UBSNavigationUtils dequeueErrorTime:args];
);

编辑:我只是想帮你清理代码。 :(

+(void)queueError:(UILabel*)messageView errorText:(NSString*)errorText
  [messageView setText:errorText];
  messageView.hidden = NO;
  NSInteger expectedTag = arc4random_uniform(UINT32_MAX);
  messageView.tag = expectedTag;
  [UIView animateWithDuration:0.3 delay:0.0 options:0 animations:^()
    messageView.alpha = 1.0;
   completion:^(BOOL finished) 
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
      [UBSNavigationUtils dequeueErrorMessage:messageView tag:expectedTag];
    );
  ];


+ (void)dequeueErrorMessage:(UILabel *)messageView tag:(NSInteger)tag 
  if(messageView.tag == tag) 
    [[UBSNavigationUtils class] fadeOutError:messageView];
  

【讨论】:

很抱歉。我还没想完就点击了保存。 哦。没问题。这非常适合我所追求的。

以上是关于延迟类选择器调用的主要内容,如果未能解决你的问题,请参考以下文章

id选择器和类选择器

从另一个类调用选择器的 UIGestureRecognizer

uibutton 添加目标选择器方法在调用类而不是在被调用类中调用

CSS选择器

UIGestureRecognizer,从另一个类调用选择器

延迟一段时间后显示 uipickerview