2011-10-17 6 views
4

Apple의 -setNeedsLayout 작동 방식을 알고 싶습니다.setNeedsLayout은 어떻게 작동합니까?

-layoutSubviews을 직접 호출하는 것보다 더 효율적이라는 것을 알고 있습니다. 메소드에서 두 번해야 할 수도 있습니다.
그리고 그게 내가 필요로하는 것입니다 :보기 컨트롤러 용으로 약간의 사용자 정의 -setNeedsValidation.
그런 기능을 실현하는 방법은 무엇입니까?

답변

5

애플이 정확히 이런 식으로 처리하는지 확인할 수는 없지만 찾고자하는 것을 할 수있는 방법이 있으며 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 문서에서 언급 한대로)에서 일정을 업데이트합니다.

따라서 -setNeedsLayoutBOOL 플래그를 설정합니다. 플래그는 나중에 확인되며 (-drawRect:?), YES으로 설정하면 -layoutSubviews이 호출됩니다. 그런 다음 플래그가 지워지고 -setNeedsLayout에 대한 다음 호출을 기다립니다.

+0

그건 내가 생각한 것입니다. 그렇다면 어떻게하면 메인 실행 루프의 다음 반복에서 실행되는 메소드를 만들 수 있습니까? –

+0

'-performSelector : withObject : afterDelay :'지연이 0 인 경우 선택자 실행을 실행 루프로 예약합니다. – ayoy

+0

그래, 그건 분명했다. 죄송합니다. –