(동일한) 함수에서 두 줄의 실행 사이에 지연을 추가해야합니다. 이를 수행하는 데 유리한 옵션이 있습니까?
참고 : 이를 위해 두 가지 다른 함수가 필요하지 않으며 지연이 다른 함수의 실행에 영향을주지 않아야합니다.
예 :
line 1: [executing first operation];
line 2: Delay /* I need to introduce delay here */
line 3: [executing second operation];
어떤 도움이라도 감사합니다. 미리 감사드립니다 …
답변
다른 방법을 만들지 않고도 gcd를 사용하여이 작업을 수행 할 수 있습니다.
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
NSLog(@"Do some work");
});
코드를 복잡하게 만들고 경쟁 조건을 유발할 수 있으므로 “정말 지연을 추가해야합니까?”라고 자문해야합니다.
답변
다음 NSThread
방법을 사용할 수 있습니다 .
[NSThread sleepForTimeInterval: delay];
그러나 메인 스레드에서이 작업을 수행하면 앱이 차단되므로 백그라운드 스레드에서만 수행하십시오.
또는 Swift에서
NSThread.sleepForTimeInterval(delay)
Swift 3에서
Thread.sleep(forTimeInterval: delay)
답변
이 행은 3 초 후에 선택기 secondMethod를 호출합니다.
[self performSelector:@selector(secondMethod) withObject:nil afterDelay:3.0 ];
원하는 지연으로 두 번째 작업에 사용하십시오. 코드가 많은 경우 자체 메서드에 배치하고 performSelector:
. UI를 차단하지 않습니다.sleep
편집 : 두 번째 방법을 원하지 않는 경우 performSelector에서 블록을 사용할 수 있도록 카테고리를 추가 할 수 있습니다.
@implementation NSObject (PerformBlockAfterDelay)
- (void)performBlock:(void (^)(void))block
afterDelay:(NSTimeInterval)delay
{
block = [block copy];
[self performSelector:@selector(fireBlockAfterDelay:)
withObject:block
afterDelay:delay];
}
- (void)fireBlockAfterDelay:(void (^)(void))block
{
block();
}
@end
또는 더 깔끔하게 :
void RunBlockAfterDelay(NSTimeInterval delay, void (^block)(void))
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC*delay),
dispatch_get_current_queue(), block);
}
답변
나는 차례를 시작하기 전에 (그리고 차례의 단계 사이) AI가 일시 중지 해야하는 몇 가지 턴 기반 게임을 가지고 있습니다. 지연이 최선의 해결책 인 다른 더 유용한 상황이 있다고 확신합니다. Swift에서 :
let delay = 2.0 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
dispatch_after(time, dispatch_get_main_queue()) { self.playerTapped(aiPlayView) }
Objective-C 호출이 다른지 확인하기 위해 방금 여기로 돌아 왔습니다 (저도 이것도 추가해야합니다).
답변
iOS 4.0 이상을 대상으로하는 경우 다음을 수행 할 수 있습니다.
[executing first operation];
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[executing second operation];
});
답변
답변
@Sunkas가 쓴 것처럼, 그것이 더 짧고 정상적인 구문 을 가지고 있다는 것만으로 performSelector:withObject:afterDelay:
펜던트 입니다. 지연하려는 블록에 인수를 전달해야하는 경우 매개 변수를 통해 전달하기 만하면 호출 에서 인수 를받을 수 있습니다.dispatch_after
objective-c
withObject
selector
[self performSelector:@selector(testStringMethod:)
withObject:@"Test Test"
afterDelay:0.5];
- (void)testStringMethod:(NSString *)string{
NSLog(@"string >>> %@", string);
}
메인 스레드 또는 현재 스레드에서 실행하는 경우 여전히 자신을 선택하고 싶다면이를 지정할 수있는 특정 메서드가 있습니다. Apples Documentation은 다음과 같이 말합니다.
실행 루프가 기본 모드가 아닌 모드에있을 때 메시지를 대기열에서 빼려면 performSelector : withObject : afterDelay : inModes : 메서드를 대신 사용하세요. 현재 스레드가 기본 스레드인지 확실하지 않은 경우 performSelectorOnMainThread : withObject : waitUntilDone : 또는 performSelectorOnMainThread : withObject : waitUntilDone : modes : 메소드를 사용하여 선택기가 기본 스레드에서 실행되도록 할 수 있습니다. 대기중인 메시지를 취소하려면 cancelPreviousPerformRequestsWithTarget : 또는 cancelPreviousPerformRequestsWithTarget : selector : object : 메소드를 사용하십시오.