Почему PerformSelector не присутствует в быстрой

очевидно, что следующее не доступно быстрее:

[self performSelector:@selector(onFlip) withObject:nil afterDelay:0.3];

почему это так, если все еще присутствует:

NSObject.cancelPreviousPerformRequestsWithTarget(self, selector: singleTapSelector, object: nil)

не работает nsobject.cancel с performSelector? почему есть функция отмены, но не выполняет функции?

Ответы

Ответ 1

Используйте

NSTimer.scheduledTimerWithTimeInterval(delay, target: self, selector: "onFlip", userInfo: nil, repeats: false)

вместо этого. Не знаю, почему другой недоступен.

Ответ 2

Мы можем легко разблокировать эти методы в Swift 1.x! Ура!

Эти методы из семейства perfromSelector фактически существуют в Swift, но они были искусственно скрыты (по дизайну, я думаю) до Swift 2.0. Они могут быть представлены с использованием swizzling и некоторых Objective-C хакеров в режиме Swift.

Просто добавьте этот файл расширения NSObject+PerformSelector.swift и префикс всех вызовов с символом 🚀.

В вашем случае код:

[self performSelector:@selector(onFlip) withObject:nil afterDelay:0.3];

можно переписать в Swift следующим образом:

self.🚀performSelector("onFlip", withObject: nil, afterDelay: 0.3)

Используя эту 🚀magical категорию (расширение класса): NSObject+PerformSelector.swift

import Foundation

private var dispatchOnceToken: dispatch_once_t = 0

private var selectors: [Selector] = [
    "performSelector:",
    "performSelector:withObject:",
    "performSelector:withObject:withObject:",
    "performSelector:withObject:afterDelay:inModes:",
    "performSelector:withObject:afterDelay:",
]

private func swizzle() {
    dispatch_once(&dispatchOnceToken) {
        for selector: Selector in selectors {
            let 🚀selector = Selector("🚀\(selector)")
            let method = class_getInstanceMethod(NSObject.self, selector)

            class_replaceMethod(
                NSObject.self,
                🚀selector,
                method_getImplementation(method),
                method_getTypeEncoding(method)
            )
        }
    }
}

extension NSObject {

    func 🚀performSelector(selector: Selector) -> AnyObject? {
        swizzle()
        return self.🚀performSelector(selector)
    }

    func 🚀performSelector(selector: Selector, withObject object: AnyObject?) -> AnyObject? {
        swizzle()
        return self.🚀performSelector(selector, withObject: object)
    }

    func 🚀performSelector(selector: Selector, withObject object1: AnyObject?, withObject object2: AnyObject?) -> AnyObject? {
        swizzle()
        return self.🚀performSelector(selector, withObject: object1, withObject: object2)
    }

    func 🚀performSelector(selector: Selector, withObject object: AnyObject?, afterDelay delay: NSTimeInterval, inModes modes: [AnyObject?]?) {
        swizzle()
        self.🚀performSelector(selector, withObject: object, afterDelay: delay, inModes: modes)
    }

    func 🚀performSelector(selector: Selector, withObject object: AnyObject?, afterDelay delay: NSTimeInterval) {
        swizzle()
        self.🚀performSelector(selector, withObject: object, afterDelay: delay)
    }

}

Ответ 3

func performFlipOnDelay() {
  let delayInSeconds = 1.0
  let delay = dispatch_time(DISPATCH_TIME_NOW, Int64(delayInSeconds * Double(NSEC_PER_SEC)))
  dispatch_after(delay, dispatch_get_main_queue()) { 
     onFlip();
  }
}

Еще один раунд ответа будет выше, используя GCD, чтобы добавить время задержки для выполняемого действия.

Ответ 4

Принимая ответ от Томаса Килиана еще на шаг, прежде всего для повышения удобочитаемости при вызове клиентов, я определил быструю утилиту TimerUtil.swift, определяющую фасад на NSTimer для этой конкретной утилиты:

import Foundation

/**
 * Convenience function to make a single timer scheduling more readable.
 */
public func invoke( selector:Selector, on target:AnyObject, afterDelay delay:NSTimeInterval ) {

    NSTimer.scheduledTimerWithTimeInterval( delay, target: target, selector: selector, userInfo: nil, repeats: false )
}

Затем ваш код может просто вызвать:

invoke( "onFlip", on:self, afterDelay:0.3 )

который более или менее похож на performSelector: withObject: afterDelay