У меня есть приложение в Objective C, которое я перехожу к Swift. В Objective C у меня есть этот метод:
[self.view performSelector:@selector(someSelector) withObject:self afterDelay:0.1f];
Я работаю с Swift, и я не могу понять, как это сделать. Я пробовал:
self.view.performSelector(Selector("someSelector"), withObject: self, afterDelay: 0.1)
Вот ошибка, которую я получаю: 'performSelector' is unavailable: 'performSelector' methods are unavailable
Какой вызов я использовал бы для вызова метода afterDelay
?
UPDATE
Вот что я закончил с:
extension NSObject {
func callSelectorAsync(selector: Selector, object: AnyObject?, delay: NSTimeInterval) -> NSTimer {
let timer = NSTimer.scheduledTimerWithTimeInterval(delay, target: self, selector: selector, userInfo: object, repeats: false)
return timer
}
func callSelector(selector: Selector, object: AnyObject?, delay: NSTimeInterval) {
let delay = delay * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
dispatch_after(time, dispatch_get_main_queue(), {
NSThread.detachNewThreadSelector(selector, toTarget:self, withObject: object)
})
}
}
Свифт 3/4
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(0.1)) {
// your function here
}
Swift 2
let dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC)))
dispatch_after(dispatchTime, dispatch_get_main_queue(), {
// your function here
})
dispatch_after
работает с очередями отправки. performSelector:afterDelay:
и NSTimer
работают с циклами выполнения.
Вы можете сделать это:
var timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("someSelector"), userInfo: nil, repeats: false)
func someSelector() {
// Something after a delay
}
let timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(someSelector), userInfo: nil, repeats: false)
func someSelector() {
// Something after a delay
}
Swift статически типизирован, поэтому методы performSelector:
должны падать на обочину.
Вместо этого используйте GCD для отправки подходящего блока в соответствующую очередь - в этом случае он, по-видимому, будет главной очередью, так как похоже, что вы выполняете работу UIKit.
EDIT: соответствующий performSelector:
также отсутствует в версии Swift версии NSRunLoop
( "1 Objective-C символ скрыт" ), поэтому вы не может прыгать прямо с этим. С этим и его отсутствием от Swiftified NSObject
я бы сказал, что это довольно ясно, что здесь думает Apple.
dispatch_get_current_queue
устарела, и получить очередь для запуска в текущем потоке (с runloop) не так просто. performSelector:
методы имеют свое место и никуда не performSelector:
.
self.view
с self.view
. Так что это, вероятно, работа UIKit. Так идет по основной очереди. В противном случае, я думаю, вам нужно @objc
атрибут @objc
для принудительного выбора селектора, несмотря на Swift, и тогда, возможно, вы будете разумно использовать NSRunLoop
напрямую, но вы можете унаследовать от NSObject
чтобы получить старые performSelector
.
afterDelay