Как я могу отложить вызов метода на 1 секунду? - PullRequest
162 голосов
/ 28 мая 2009

Есть ли простой способ отложить вызов метода на 1 секунду?

У меня есть UIImageView, который реагирует на событие касания. При обнаружении касания в приложении происходят некоторые анимации. Через одну секунду я хочу вызвать другой метод. В этом случае я не могу использовать селектор animationDidStop.

Ответы [ 11 ]

253 голосов
/ 28 мая 2009
performSelector:withObject:afterDelay:

Ссылка на документ

191 голосов
/ 22 марта 2012

Вы также можете использовать блок

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

В большинстве случаев вы захотите использовать dispatch_get_main_queue, хотя, если в методе нет интерфейса, вы можете использовать глобальную очередь .

Edit:

Swift 3 версия:

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

Точно так же, DispatchQueue.global().asyncAfter(... также может быть хорошим вариантом.

125 голосов
/ 03 октября 2011

Лучший способ сделать это:

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

вы также можете передать nil как параметр withObject.

пример:

[self performSelector:@selector(subscribe) withObject:self afterDelay:3.0 ];
24 голосов
/ 02 апреля 2015

Ответов уже много, и все они верны. Если вы хотите использовать dispatch_after, вы должны искать фрагмент, который находится внутри Code Snippet Library справа внизу (где вы можете выбрать UI элементы).

enter image description here

Так что вам просто нужно вызвать этот фрагмент, написав dispatch в коде:

enter image description here

17 голосов
/ 03 октября 2011

Вы можете использовать селектор выполнения после того, как метод задержки 0,1 с вызывает этот следующий код, чтобы сделать это.

[self performSelector:@selector(InsertView)  withObject:nil afterDelay:0.1]; 
9 голосов
/ 02 марта 2014

Вы также можете:

[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(); });
}
7 голосов
/ 25 марта 2015

Вы можете сделать это

[self performSelector:@selector(MethodToExecute) withObject:nil afterDelay:1.0 ];
4 голосов
/ 20 декабря 2016

Swift 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")
}

Swift 3.x - & - Swift 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 голос
/ 04 октября 2016

Существует решение Swift 3 из проверенного решения:

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

А есть метод

@objc fileprivate func targetMethod(){

}
0 голосов
/ 29 августа 2017

Использование в Swift 3

perform(<Selector>, with: <object>, afterDelay: <Time in Seconds>)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...