2011-10-17 12 views
4

我想知道蘋果的-setNeedsLayout是如何工作的。setNeedsLayout如何工作?

我已經知道它比直接調用-layoutSubviews更有效率,因爲我可能需要在方法中做兩次。
而這正是我需要的:視圖控制器的一些自定義-setNeedsValidation
但是如何實現這樣的功能呢?

回答

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

只是想一想...文檔說-setNeedsLayout在下一個「更新週期」(或「繪圖更新」,如-layoutSubviews文檔中提到的)安排佈局更新。

因此-setNeedsLayout最有可能設置一個BOOL標誌。稍後檢查該標誌(在-drawRect:?中),如果它設置爲YES,則調用-layoutSubviews。然後該標誌被清除並等待下一次呼叫-setNeedsLayout

+0

這就是我的想法。那麼,如何讓主運行循環的下一次迭代中執行一個方法? – 2011-10-17 13:22:29