2

我正在寻找类似的行为

[[NSNotificationQueue defaultQueue] enqueueNotification:not postingStyle:NSPostWhenIdle coalesceMask:NSNotificationCoalescingOnName|NSNotificationCoalescingOnSender forModes:nil];

但不使用通知,以某种方式将选择器或块排入队列而不是通知。

至于我的动机(只是看看这是否是一种合法的做法)。我在一个视图中添加了多个子视图,显然没有办法知道有多少,所以每次我添加一个子视图时,我都必须通过调用layoutIfNeeded以特定方式布局子视图来执行一些计算。现在,我在想,如果我只能在 runloop 空闲时调用该方法(以某种方式推迟调用并合并它),那么在它执行布局计算时所有子视图都已经添加了。希望这是有道理的。

-(void)layoutSubviews
{
[super layoutSubviews];


UIView* prevView = nil;
for (NSUInteger i=0; i<[self.subviews count]; i++) {
    UIView* view = self.subviews[i];
    CGFloat spacing = prevView!=nil?self.spacing:0;
    view.topLeft = CGPointOffset(prevView.bottomLeft, spacing, 0);
    prevView = view;
}

[self fitSubviews];
}

添加了我的layoutSubview方法中的代码。

4

1 回答 1

1

对于一般问题,最简单的解决方案是:

- (void)setNeedsCustomTask
{
    // cancel any previously scheduled call to perform the task
    [NSObject
         cancelPreviousPerformRequestsWithTarget:self
         selector:@selector(doCustomTask)
         object:nil];

    // schedule a new call; because you've specified any delay
    // at all this will be scheduled to occur in the future rather than
    // right now and because you've specified a 0.0 delay it'll be
    // as soon as possible in the future
    [self performSelector:@selector(doCustomTask) withObject:nil afterDelay:0.0];
}

- (void)doCustomTask
{
    NSLog(@"I am a custom task");
}

之所以有效,是因为performSelector:withObject:afterDelay:将来会在 runloop 上安排调用。您还可以指定inModes:例如是否要避免跟踪模式。

在取消和重新安排而不是在手边保留一个标志时,显然存在一些技术上的低效率,但它很整洁,因为您不需要明确地编组状态。所以我认为首先这样做会有一个很好的过早优化论据。

于 2013-02-13T19:39:17.577 回答