开发者

How does setNeedsLayout work?

开发者 https://www.devze.com 2023-04-13 08:18 出处:网络
I would like to know how Apple\'s -setNeedsLayout works. I already know that it\'s more efficient than directly calling -layoutSubviews, since I might need to do that twice in a method.

I would like to know how Apple's -setNeedsLayout works.

I already know that it's more efficient than directly calling -layoutSubviews, since I might need to do that twice in a method.

And that's just what I need it for: some custom -setNeedsValidation for a view controller.

But how to realize s开发者_开发技巧uch a feature?


I can't confirm that Apple does it exactly this way, but here is a way to do what you're looking for, and is likely similar to how setNeedsLayout is implemented. I haven't tested this (or even compiled it), but it should give an idea of how to attack the problem as a category on UIViewController. Like UIKit, this is completely thread-unsafe.

static NSMutableSet sViewControllersNeedingValidation = nil;
static BOOL sWillValidate = NO;

@implementation UIViewController (Validation)
+ (void)load {
  sViewControllersNeedingValidation = [[NSMutableSet alloc] init];
}

- (void)setNeedsValidation {
  [sViewControllersNeedingValidation addObject:self];

  if (! sWillValidate) {
    sWillValidate = YES;
    // Schedule for the next event loop
    [[self class] performSelector:@selector(dispatchValidation) withObject:nil afterDelay:0];
  }
}

+ (void)dispatchValidation {
  sWillValidate = NO;
  // The copy here is in case any of the validations call setNeedsValidation.
  NSSet *controllers = [sViewControllersNeedingValidation copy];
  [sViewControllersNeedingValidation removeAllObjects];
  [controllers makeObjectsPerformSelector:@selector(validate)];
  [controllers release];
}

- (void)validate {
  // Empty default implementation
}


Just thinking out loud... Documentation says that -setNeedsLayout schedules layout update in the next "update cycle" (or "drawing update", as mentioned in -layoutSubviews docs).

So -setNeedsLayout most probably sets a BOOL flag. The flag is checked later on (in -drawRect:?) and if it's set to YES, -layoutSubviews is called. Then the flag is cleared and waiting for next calls to -setNeedsLayout.

0

精彩评论

暂无评论...
验证码 换一张
取 消