Swift executeSelector: withObject: afterDelay: недоступно

123

У меня есть приложение в 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)
        })
    }
}
  • 9
    Я бы не согласился. Я не спрашиваю, как выполнить селектор. Я спрашиваю, как выполнить селектор после afterDelay
  • 0
    Там же ответили на этот вопрос. Используйте GCD и dispatch_after или dispatch_async.
Показать ещё 4 комментария
Теги:
xcode6

3 ответа

156

Свифт 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 
})
  • 2
    Но это другое. dispatch_after работает с очередями отправки. performSelector:afterDelay: и NSTimer работают с циклами выполнения.
  • 0
    И ваша точка зрения? GCD отлично подходит здесь ...
Показать ещё 11 комментариев
108

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

var timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("someSelector"), userInfo: nil, repeats: false)

func someSelector() {
    // Something after a delay
}

SWIFT 3

let timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(someSelector), userInfo: nil, repeats: false)

func someSelector() {
    // Something after a delay
}
  • 1
    Хорошо спасибо. Я попробую это.
  • 0
    Просто обратите внимание, что этот метод работает, только если ваш класс наследуется от NSObject или производного класса. Это не будет работать в чистом быстром классе.
Показать ещё 6 комментариев
9

Swift статически типизирован, поэтому методы performSelector: должны падать на обочину.

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

EDIT: соответствующий performSelector: также отсутствует в версии Swift версии NSRunLoop ( "1 Objective-C символ скрыт" ), поэтому вы не может прыгать прямо с этим. С этим и его отсутствием от Swiftified NSObject я бы сказал, что это довольно ясно, что здесь думает Apple.

  • 1
    Это проблема. dispatch_get_current_queue устарела, и получить очередь для запуска в текущем потоке (с runloop) не так просто. performSelector: методы имеют свое место и никуда не performSelector: .
  • 0
    Здесь это не выглядит проблемой - он хочет, чтобы селектор self.view с self.view . Так что это, вероятно, работа UIKit. Так идет по основной очереди. В противном случае, я думаю, вам нужно @objc атрибут @objc для принудительного выбора селектора, несмотря на Swift, и тогда, возможно, вы будете разумно использовать NSRunLoop напрямую, но вы можете унаследовать от NSObject чтобы получить старые performSelector .
Показать ещё 8 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню