2

私はに似た行動を探しています

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

ただし、通知を使用せずに、何らかの方法で通知の代わりにセレクターまたはブロックをキューに入れます。

私の動機については(これが正当な方法であるかどうかを確認するためです)。複数のサブビューをビューに追加しますが、明らかにその数を知る方法はありません。そのため、サブビューを追加するlayoutIfNeededたびに、特定の方法でサブビューをレイアウトするために呼び出して計算を実行する必要があります。ここで、実行ループがアイドル状態になったときにのみメソッドを呼び出すことができれば (何らかの方法で呼び出しを延期して合体させる)、レイアウト計算を実行するまでにすべてのサブビューが既に追加されていると考えていました。それが理にかなっていることを願っています。

-(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 に答える