NSTimer找不到selector [duplicate]

时间:2022-09-22 16:55:15

This question already has an answer here:

这个问题已经有了答案:

I want to use an NSTimer in a class that doesn't inherit from UIViewVontroller. I have 2 files : a ViewController and a TimerClass like that :

我想在没有继承自UIViewVontroller的类中使用NSTimer。我有两个文件:一个ViewController和一个TimerClass:

ViewController:

ViewController:

import UIKit

class ViewController: UIViewController {

    var timerClass = TimerClass()

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewDidAppear(animated: Bool) {
        timerClass.launchTimer()
    }

}

TimerClass :

TimerClass:

import Foundation

class TimerClass {

    var timer = NSTimer()

    init(){}

    func launchTimer(){
        var timer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: "timerEnd", userInfo: nil, repeats: true)
    }

    func timerEnd(){
        println("That worked")
    }
}

When I launch that app, I have a crash with :

当我启动这个应用程序时,我崩溃了:

2015-01-12 19:48:24.322 Timer_TEST[5829:185651] *** NSForwarding: warning: object 0x7fbc3be20710 of class 'Timer_TEST.TimerClass' does not implement methodSignatureForSelector: -- trouble ahead Unrecognized selector -[Timer_TEST.supportFile timerEnd]

2015-01-12 19:48:24.322 Timer_TEST[5829:185651] *** NSForwarding:警告:class 'Timer_TEST的对象0x7fbc3be20710。TimerClass'没有实现methodSignatureForSelector:——前面的问题无法识别selector -[Timer_TEST。supportFile timerEnd]

Any idea?

任何想法?

Thank you

谢谢你!

1 个解决方案

#1


29  

EDIT: Note that starting in Swift 2.2 you won't be able to make this mistake! You'll use the new #selector syntax (see https://*.com/a/35658335/341994), and the compiler won't let you form a selector for a method that isn't exposed to Objective-C.

编辑:注意,从Swift 2.2开始,你不会犯这个错误!您将使用新的#selector语法(参见https://*.com/a/35658335335 /341994),编译器不会让您为不公开给Objective-C的方法构造一个selector。


It's merely a question of exposing the Swift function to Objective-C so that it is visible to Objective-C. You have four choices:

这仅仅是一个将Swift函数暴露给Objective-C的问题,这样它就可以被Objective-C看到。你有四个选择:

  • Make TimerClass descend from NSObject (and delete the init implementation):

    使TimerClass从NSObject派生(并删除init实现):

    class TimerClass : NSObject {
    
  • Declare TimerClass with @objc [not in Swift 2.0; use the previous choice instead]:

    使用@objc声明TimerClass[不在Swift 2.0中;用先前的选择代替]:

    @objc TimerClass {
    
  • Declare the function with @objc:

    使用@objc声明功能:

    @objc func timerEnd()
    
  • Declare the function dynamic (this is probably the worst choice, as it is unnecessary - the function is not dynamic; it does not need to be altered in place by Objective-C, it just needs to be visible):

    声明函数动态(这可能是最坏的选择,因为它是不必要的——函数不是动态的;它不需要被Objective-C修改,它只需要可见):

    dynamic func timerEnd(){
    

#1


29  

EDIT: Note that starting in Swift 2.2 you won't be able to make this mistake! You'll use the new #selector syntax (see https://*.com/a/35658335/341994), and the compiler won't let you form a selector for a method that isn't exposed to Objective-C.

编辑:注意,从Swift 2.2开始,你不会犯这个错误!您将使用新的#selector语法(参见https://*.com/a/35658335335 /341994),编译器不会让您为不公开给Objective-C的方法构造一个selector。


It's merely a question of exposing the Swift function to Objective-C so that it is visible to Objective-C. You have four choices:

这仅仅是一个将Swift函数暴露给Objective-C的问题,这样它就可以被Objective-C看到。你有四个选择:

  • Make TimerClass descend from NSObject (and delete the init implementation):

    使TimerClass从NSObject派生(并删除init实现):

    class TimerClass : NSObject {
    
  • Declare TimerClass with @objc [not in Swift 2.0; use the previous choice instead]:

    使用@objc声明TimerClass[不在Swift 2.0中;用先前的选择代替]:

    @objc TimerClass {
    
  • Declare the function with @objc:

    使用@objc声明功能:

    @objc func timerEnd()
    
  • Declare the function dynamic (this is probably the worst choice, as it is unnecessary - the function is not dynamic; it does not need to be altered in place by Objective-C, it just needs to be visible):

    声明函数动态(这可能是最坏的选择,因为它是不必要的——函数不是动态的;它不需要被Objective-C修改,它只需要可见):

    dynamic func timerEnd(){