我想知道Apple的-setNeedsLayout
是如何运作的。
我已经知道它比直接调用-layoutSubviews
更有效率,因为我可能需要在方法中执行两次。
这正是我所需要的:视图控制器的一些自定义-setNeedsValidation
但是如何实现这样的功能?
答案 0 :(得分: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
}
答案 1 :(得分:1)
大声思考......文档说明-setNeedsLayout
会在下一个“更新周期”(或“图纸更新”中安排布局更新,如-layoutSubviews
文档中所述)。
所以-setNeedsLayout
最有可能设置BOOL
标志。稍后会检查该标记(在-drawRect:
?中),如果设置为YES
,则会调用-layoutSubviews
。然后清除该标志并等待下一次调用-setNeedsLayout
。