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.
-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
.
精彩评论