1 초 동안 메소드 호출을 어떻게 지연시킬 수 있습니까?


164

1 초 동안 메소드 호출을 지연시키는 쉬운 방법이 있습니까?

나는이 UIImageView터치 이벤트에 그 반응하여합니다. 터치가 감지되면 앱에서 일부 애니메이션이 발생합니다. 1 초 후에 다른 방법을 호출하고 싶습니다. 이 경우 animationDidStop셀렉터를 사용할 수 없습니다 .


그렇게 할 확실히 여러 가지 방법으로, 그 중 하나는 단순히 밀리 세컨드의 수에 대한 프로그램 / 스레드를 일시 중단 수면 ()를 사용하는 수도 있습니다 하지만 난 당신이에 의해 달성하기 위해 노력하고 정확하게 우리에게 얘기를 할 수 있습니다 생각 그렇게합니까? 당신의 실제 문제는 무엇입니까? 메소드 호출을 지연시키는 아이디어는 '솔루션'인 것 같습니다. 솔직히 말하기에는 너무 좋지 않은 것 같습니다. 따라서 염두에 둔 시나리오에 대해 자세히 알려주십시오.
none

답변:


254
performSelector:withObject:afterDelay:

문서 참조


7
이것이 정답입니다. 참조하십시오 developer.apple.com/DOCUMENTATION/Cocoa/Reference/Foundation/...을 :
해치는

호출 된 메소드의 반환 값이있는 방법이 있습니까? 또는 정보를 다시 얻으려면 매개 변수를 수정하도록 설정해야합니까?
고든 구스타프 슨

누군가 예약 된 호출을 취소하는 방법에 관심이있는 경우 : [NSObject cancelPreviousPerformRequestsWithTarget : yourTarget 선택기 : aSelector 객체 : anArgument];
vir us

192

당신은 또한 블록을 사용할 수 있습니다

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
    [object method]; 
});

메소드에 UI가 없으면 전역 큐를 사용할 수 있지만 대부분의 경우 dispatch_get_main_queue를 사용하려고합니다 .

편집하다:

스위프트 3 버전 :

DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
    object.method()
}

마찬가지로 DispatchQueue.global().asyncAfter(...좋은 옵션 일 수도 있습니다.


직선형 C와 ObjC를 혼합 할 때이 솔루션이 performSelector보다 쉽다는 것을 알았습니다.
Paul Slocum

1
불행히도 dispatch_get_current_queue는 iOS6부터 더 이상 사용되지 않습니다
chrisben

3
dispatch_get_current_queue 대신 dispatch_get_main_queue를 사용하도록 업데이트되었습니다.
mcfedr

2
Xcode는 이제 이것을 자동 완성 할 것입니다. 입력을 시작 dispatch_after하고 엔터를 누르십시오
mcfedr

1
특히 Xcode dispatch_after는을 입력 할 때 이것을 자동 완성합니다. 이것은 실제로 매우 간단한 방법이며 호출하는 메소드에 속성을 전달할 수 있습니다.
Erik van der Neut

128

가장 좋은 방법은 다음과 같습니다.

[self performSelector:@selector(YourFunctionName) 
           withObject:(can be Self or Object from other Classes) 
           afterDelay:(Time Of Delay)];

withObject 매개 변수로 nil을 전달할 수도 있습니다.

예 :

[self performSelector:@selector(subscribe) withObject:self afterDelay:3.0 ];

3
왜 자기를 자기에게 넘겨 주겠습니까?
Eric

2
그리고 왜 인수가없는 메소드에 변수를 전달할까요?
hellozimi

23

이미 많은 답변이 있으며 모두 정확합니다. 사용하려는 경우 오른쪽 하단의 요소를 선택할 수 dispatch_after있는 스 니펫을 찾아야합니다 .Code Snippet LibraryUI

여기에 이미지 설명을 입력하십시오

따라서 코드로 디스패치 를 작성하여이 스 니펫을 호출하면됩니다 .

여기에 이미지 설명을 입력하십시오


16

이를 위해 0.1 초 지연 메소드가 호출 된 후 수행 선택기를 사용하여 다음 코드를 호출 할 수 있습니다.

[self performSelector:@selector(InsertView)  withObject:nil afterDelay:0.1]; 

9

당신은 또한 수:

[UIView animateWithDuration:1.0
                 animations:^{ self.view.alpha = 1.1; /* Some fake chages */ }
                 completion:^(BOOL finished)
{
    NSLog(@"A second lapsed.");
}];

이 경우 애니메이션 작업을하려면보기를 약간 변경해야합니다. 실제로 해 키지 만 블록 기반의 물건을 좋아합니다. 또는 아래 @mcfedr 답변을 마무리하십시오.


waitFor(1.0, ^
{
    NSLog(@"A second lapsed");
});

typedef void (^WaitCompletionBlock)();
void waitFor(NSTimeInterval duration, WaitCompletionBlock completion)
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, duration * NSEC_PER_SEC),
                   dispatch_get_main_queue(), ^
    { completion(); });
}

확실하지 않지만, 제안하는 첫 번째 옵션은 UI의 일부에서 사용자 상호 작용을 차단하는 등 사용자가 알아야 할 부작용이있을 수 있습니다. 내 본능은 불필요한 CPU 또는 기타 리소스 소모를 유발하지만 확인하지는 않았다는 것입니다.
Bjorn Roche

8

당신은 이것을 할 수 있습니다

[self performSelector:@selector(MethodToExecute) withObject:nil afterDelay:1.0 ];

4

스위프트 2.x

let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
 dispatch_after(delayTime, dispatch_get_main_queue()) {
 print("do some work")
}

스위프트 3.x-&-스위프트 4

DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
    print("do some work")
}

또는 통과 escaping closure

func delay(seconds: Double, completion: @escaping()-> Void) {
    DispatchQueue.main.asyncAfter(deadline: .now() + seconds, execute: completion)
}

1

확인 된 솔루션의 Swift 3 솔루션이 있습니다.

self.perform(#selector(self.targetMethod), with: self, afterDelay: 1.0)

그리고 방법이 있습니다

@objc fileprivate func targetMethod(){

}


-34

참고 : 이렇게하면 한 가지 방법이 아닌 전체 스레드가 일시 중지됩니다.
메소드를 호출하기 직전에 1000ms 동안 휴면 / 대기 / 중지 호출을 하시겠습니까?

Sleep(1000); // does nothing the next 1000 mSek

Methodcall(params); // now do the real thing

편집 : 위의 답변은 일반적인 질문 "어떻게 1 초 동안 메소드 호출을 지연시킬 수 있습니까?"에 적용됩니다. )). 그 당시에는 언어에 대한 정보가 없었으므로 수면을 사용하는 적절한 방법에 대해 친절하게 말하지 마십시오.


현재 스레드에서만 다른 스레드가 계속 실행됩니다.
Marc Charbonneau

4
이런. 나는 이것이 왜 몇 번이나 투표를했는지 알지만 도대체 누가 이것을 -27에서 보았고 또 다른 것이 필요하다고 결정 했습니까? -3 또는 무언가가 요점을 얻지 못합니다. 왜 "이것은 전체 스레드를 일시 중지합니다"또는 사람들을 내리는 대신 무언가라고 말하는 대답을 편집하지 않습니까?
Albert Renshaw

전체 스레드를 일시 중지하려면 어떻게해야합니까? 괜찮은 경고가 나오면 유효한 옵션처럼 보입니다.
Departamento B

@AlbertRenshaw 나는 당신에게 전적으로 동의합니다. 나는 여기에 있으며 35 다운입니다. 평판이 좋지 않은 사용자를 공격하는 것이 더 심하게 보입니다. 아무도 편집하거나 아무것도 지정하지 않습니다. 나는 오늘 익사 한 것에 대한 답을 보았습니다. 그 사람이 한 유일한 실수는 객관적인 c 언어로 신속한 질문에 대답하는 것입니다. 그것이 큰 실수라면, 나는 객관적인 c 질문 아래에 많은 신속한 답변을 보여주고 싶습니다.
soorej babu
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.