2010-02-12 3 views
3

나는 아이폰의 Objective-C 이벤트 모델에 대해 머리를 쓰려고 노력하고 있으며, 근본적으로 여기서 오해 한 것들을 보았다.UI를 업데이트하기 전에 viewDidLoad가 대기하는 이유는 무엇입니까?

보기 컨트롤러의 -viewDidLoad 메서드에서 UILabel의 텍스트를 설정하고 2 초 동안 잠자기 한 다음 레이블의 텍스트를 다시 변경합니다.

내 기대치는 다음과 같습니다. 레이블에 "First Text"가 먼저 표시되고 2 초 후 "Second Text"로 업데이트됩니다. 물론, 이것이 실제로 어떻게 일어나는 것이 아닙니다. 대신,보기는 에 전혀 표시되지 않고 2 초 동안 표시되고 마지막으로 표시되면 해당 레이블에 "두 번째 텍스트"가 표시됩니다.

누군가 제발 나에게 무슨 일이 일어나는지 설명해 주시겠습니까? 나는 너희들이 내가 여기 갈 일을 어떻게 성취 할 수 있는지에 대해 관심이있다.

건배.

UPDATE 1은 :

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    label.text = @"First Label"; 
    sleep(2); 
    label.text = @"Second Label"; 
} 

업데이트 2 : 여기에있는 viewDidLoad 방법이다 내가 지금이 업데이트를 무시하세요, 여기에 바보 같은 실수를했다.

UPDATE 3는 :

- (void)viewDidAppear: (BOOL)animated { 
    [super viewDidAppear: animated]; 
    label.text = @"First Label"; 
    sleep(2); 
    label.text = @"Second Label"; 
} 

불행하게도 나는 정확히 같은 문제에 봉착 : 나는 지금 내 viewDidAppear 방법에 다음과 같은 추가했습니다.

업데이트 4 : gerry3 및 Felix의 제안에 따라 필자는 performSelector를 구현하여 호황을 누리고 있습니다. 치료를해라 !! 그가 확실히 나를 도와 주는데 많은 노력을 기울 였기 때문에 나는 그것을 gerry3에게 주어야 할 것입니다. 모든 기여에 감사드립니다!

답변

3

보기를 수정하는 코드를 viewDidAppear:에 넣으십시오.

viewDidLoadviewWillAppear:을 호출하면보기가 표시되지 않습니다.

UPDATE
그냥 명확하게하기 위해, 나는이 작업을 수행하는 올바른 방법은 지연 메소드 호출 또는 타이머 것을 다른 사람들과 동의합니다.

- (void)viewDidLoad { 
    [super viewDidLoad]; 
} 

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 

    NSLog(@"View will appear!"); 
} 

- (void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 

    NSLog(@"View did appear!"); 

    label.text = @"First Label"; 
    sleep(2); 
    label.text = @"Second Label"; 
} 

을 그리고 "올바른"방법 : 다음 업데이트 2

내가 제안하고있는 코드 나는 이유는 추측

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    label.text = @"First Label"; 
} 

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 

    NSLog(@"View will appear!"); 
} 

- (void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 

    NSLog(@"View did appear!"); 

    [self performSelector:@selector(changeLabelText) withObject:nil afterDelay:2.0f]; 
} 

- (void)changeLabelText { 
    label.text = @"Second Label"; 
} 
+0

건배 Gerry. viewDidAppear 및 viewWillAppear 메서드를 사용하여 원래 질문을 업데이트했습니다. –

+0

올바른 메서드 시그니처를 사용해야합니다. 뷰 * 표시 : 호출에는 부울 인수 (일반적으로 "애니메이션")가 있습니다. 그래서 콜론으로 이름을 마쳤습니다. 또한, 둘 모두에 대해 super를 호출하고 인수를 전달해야합니다. – gerry3

+0

완벽. 코드의 마지막 덩어리는 제가 찾고있는 것입니다. 고마워, 제리. –

4

그에 viewDidLoad 실행 mainThread는 모든 UIKit 상호 작용을합니다. UI는 mainThread에서만 업데이트 될 수 있습니다. 따라서으로 viewDidLoad를 차단하면 mainThread를 잠자기 상태로 설정하고 해당 스레드의 모든 사용자 인터페이스 업데이트를 중단합니다.

sleep(2)을 사용하는 대신 특정 시간 후에 UI를 업데이트하려면 NSTimer을 사용하십시오. 또는 자체에 performSelector:withDelay:을 사용하여 나중에 mainThread를 차단하지 않고 메소드를 수행하십시오.

viewDidAppearviewWillAppear에 대해서도 마찬가지입니다. 둘 다 mainThread에서 실행됩니다.

+0

흠 ... 이것은 많은 의미를 가지며 그것이하는 일을하는 이유를 설명합니다. 내 다음 질문은 물론 그렇게하지 않도록 설정하는 방법입니다. 나는 충분한 평판이 있다면 너를 투표 하겠어! –

+0

이 답변은 정확하지 않습니다. 내 대답은 설명과 같이 viewDidLoad 및 viewWillAppear :이 호출 될 때 뷰가 아직 보이지 않기 때문에 David가보고있는 동작이 예상됩니다. 그러나 코드가'viewDidAppear :'로 옮겨지면 원하는대로 동작합니다. – gerry3

+0

'viewDidLoad' 메쏘드는'viewDidAppear' 바로 전에 호출되므로,'performSelector : withDelay :'라고 부르는 곳에서 약간의 차이를 만들어야합니다. mainThread에 대한 상세한 설명이 잘못 되었습니까? 그렇지 않으면 수면 (2)을 viewDidLoad에 넣으면 그에 따라 viewWillAppear가 연기됩니다. – FelixLam

0

나는 그 방법으로 수면을 실제로하고 싶다고 생각하지 않습니다. 이것은 UI와 애플리케이션 전체를 막지 않기 위해 Timer를 사용해 봐야하는 것입니다. 타이머를 사용하면 코드를 하나 또는 반복해서 호출 할 수 있습니다.

0

viewDidAppear와 viewWillAppear이 sample..they의 잘못의 서명이 메시지 발송하지 않는 것처럼 프레임 워크가 잘못된 서명 구현을 호출하지 않습니다

- (void)viewWillAppear: (BOOL)animated { 
    NSLog(@"View will appear!"); 
} 

-(void)viewDidAppear : (BOOL)animated { 
    NSLog(@"View did appear!"); 
} 

해야 더 많은 정보를 위해 guide를 참조하십시오 그들을 찾아라.

+0

수정. 나는 대답에 대한 언급에서이를 언급했다. 또한, 나는 슈퍼를 불러야한다고 생각합니다. – gerry3

+0

Kevin을 지적 해 주셔서 감사합니다. 죄송합니다. –

관련 문제