4

我想知道苹果的-setNeedsLayout工作原理。

我已经知道它比直接调用更有效-layoutSubviews,因为我可能需要在一个方法中执行两次。
这正是我所需要的:-setNeedsValidation视图控制器的一些自定义。
但是如何实现这样的功能呢?

4

2 回答 2

5

我无法确认 Apple 确实是这样做的,但这里有一种方法可以满足您的需求,并且可能与setNeedsLayout实现方式类似。我没有对此进行测试(甚至没有对其进行编译),但它应该可以让您了解如何将问题作为UIViewController. 和 UIKit 一样,这完全是线程不安全的。

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
}
于 2011-10-17T13:29:42.317 回答
1

只是大声思考......文档说-setNeedsLayout在下一个“更新周期”(或“绘图更新”,如-layoutSubviews文档中所述)中安排布局更新。

所以-setNeedsLayout很可能设置了一个BOOL标志。稍后检查该标志(在-drawRect:?),如果它设置为YES-layoutSubviews则调用。然后标志被清除并等待下一次调用-setNeedsLayout.

于 2011-10-17T13:21:06.857 回答