2016-08-06 5 views
2

У меня есть функция внутри другой функции. в function1 я хочу использовать NSTimer называть func2 через некоторое время, как это:Передача быстрой функции в NSTimer

func myFunc1() 
{ 
    NSTimer.scheduledTimerWithTimeInterval(1, target: ??, selector:#selector(myFunc2()), userInfo: nil, repeats: false) 
    func myFunc2() 
    { 
     // do something... 
    } 
} 

Что такое право «цель» значение, которое я должен пройти там? это даже возможно?

+0

Вы не можете сделать это, объявите myFunc2 как метод класса –

+0

@ DanielKrom, вы имеете в виду метод _instance на верхнем уровне класса_ (или что-то в этом роде), может быть? – holex

+0

@holex Да, забыл, что метод класса означает статичный здесь –

ответ

4

Если вы настроили таргетинг на pre-iOS 10, вы не можете передать функцию NSTimer, потому что тогда API не был введен для поддержки обратных вызовов замыкания.

IOS 10, а затем подход

// swift 2.x users should still use NSTimer instead 
Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true) { timer in 
    // ... 
} 

Общий подход

Вы можете добавить этот класс, и использовать его в любое время:

final class TimerInvocation: NSObject { 

    var callback:() ->() 

    init(callback: @escaping() ->()) { 
     self.callback = callback 
    } 

    func invoke() { 
     callback() 
    } 
} 

extension Timer { 

    static func scheduleTimer(timeInterval: TimeInterval, repeats: Bool, invocation: TimerInvocation) { 

     Timer.scheduledTimer(
      timeInterval: timeInterval, 
      target: invocation, 
      selector: #selector(TimerInvocation.invoke(timer:)), 
      userInfo: nil, 
      repeats: repeats) 
    } 
} 

С помощью этого класса, вы можете просто сделайте это сейчас:

let invocation = TimerInvocation { 
    /* invocation code here */ 
} 

NSTimer.scheduledTimerWithTimeInterval(1, target: invocation, selector:#selector(TimerInvocation.invoke), userInfo: nil, repeats: false) 

Вам не придется беспокоиться о сохранении переменной invocation, поскольку она удерживается NSTimer

+1

Вы MAN! :) –

+0

Это указывает на открытый вопрос. Будет ли Swift иметь чистую, современную, быструю функцию таймера, как часть стандартной библиотеки? Он должен принять закрытие в качестве параметра. Класс Dispatch в Swift 3 близок ... –

+1

@ DuncanC Да, основа Foundation, а также другие медленно, но наверняка будут адаптироваться к Swift с течением времени. На данный момент лучшее, что вы можете сделать, это написать тонкие обертки, чтобы упростить разработку Swift. Когда появятся новые API-интерфейсы, удаление ненужных зависимостей будет легко. Например, проверьте [kitz] (http://kitz.io). Он завершает «NSNotificationCenter», поэтому вы можете пройти закрытие. – Mazyod

3

В Swift 3, новый Timer имеет фабричный метод, который принимает закрытия:

Timer.scheduledTimer(withTimeInterval: TimeInterval, repeats: Bool, block: (Timer) -> Void) 

В вашем случае вы можете назвать это так, используя синтаксис закрывающего закрытия:

Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { _ in 
    // do something 
} 

Примечание: Это доступно только в iOS 10 или новее.

+0

Но это не работает в iOS9, правильно? – Fattie

+1

@JoeBlow, правильно. Это стало доступно в iOS10. – vacawama

+0

Идеальная информация, спасибо. – Fattie