클래스 Y의 개체 X는 Swift에서 methodSignatureForSelector를 구현하지 않습니다.


89

여러 번 인스턴스화되는 Person 클래스가 있습니다. 각 사람은 자신의 타이머를 얻습니다. 내에서시 init를 위해 Person내가 전화 startTimer().

class Person {
 var timer = NSTimer()
 func startTimer() {
    timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("timerTick"), userInfo: nil, repeats: true)
 }

 func timerTick() {
    angerLevel++
    println("Angry! \(angerLevel)")
 }
...
...
}

따라서 배열에 Person 인스턴스가 3 개있을 수 있습니다 Person[]. 오류가 발생합니다.

2014-06-25 13:57:14.956 ThisProgram[3842:148856] *** NSForwarding: warning: object 0x113760048 of class '_TtC11ThisProgram6Person' does not implement methodSignatureForSelector: -- trouble ahead

나는 내가 상속해야 할 다른 곳에서 읽었 NSObject지만 이것은 Obj-C가 아닌 Swift에 있습니다. 함수가 클래스 내에 있으므로 무엇을해야할지 모르겠습니다.


4
이미 클래스가 NSObject :에서 상속해야한다는 것을 알아 냈습니다 class Person : NSObject { ... }. 다른 솔루션을 찾고 계십니까?
Martin R

답변:


160

NSObjectObjective-C 클래스로 생각하지 말고 Cocoa / Foundation 클래스로 생각하십시오. Objective-C 대신 Swift를 사용하더라도 여전히 동일한 프레임 워크를 모두 사용하고 있습니다.

두 가지 옵션 : (1) dynamic선택기로 참조하려는 함수에 속성을 추가합니다 .

    dynamic func timerTick() {
        self.angerLevel++
        print("Angry! \(self.angerLevel)")
    }

또는 (2) Person의 하위 클래스로 선언 NSObject한 다음 super.init()이니셜 라이저 시작 부분에서 호출 하십시오.

class Person: NSObject {
    var timer = NSTimer()
    var angerLevel = 0

    func startTimer() {
        print("starting timer")
        timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "timerTick", userInfo: nil, repeats: true)
    }

    func timerTick() {
        self.angerLevel++
        print("Angry! \(self.angerLevel)")
    }

    override init() {
        super.init()
        self.startTimer()
    }
}

3
또한 이와 같이 함수 선언을 장식 할 수 있어야합니다 @objc func timerTick(). NSTimer API는 Obj-C 런타임에 상당히 의존하는 것 같습니다.
macshome 2014-06-25

좋은 전화-답변에 추가
Nate Cook

1
이 문제를 해결해 주셔서 감사합니다. 하지만 이유를 설명해 주시겠습니까? @objc 부분이 필요한 것은 무엇입니까?
Aggressor

NSTimer기본적으로 Swift 유형에서 처리되지 않는 Objective-C 기능인 대상 선택기를 호출하기 위해 메시지 전달을 사용합니다. @objc속성 을 사용 하거나 Objective-C 클래스에서 상속하면 메시지 전달을 포함한 여러 기능을 선택하게됩니다.
Nate Cook

2
이러한 솔루션은 더 이상 필요하지 않습니다. 선택기 함수를 선언하는 것으로 충분합니다 dynamic. 둘 다 훌륭하고 둘 다 여전히 작동하지만 dynamic이 하나의 기능을 사용 하는 것이 더 가벼운 접근 방식으로 보일 수 있습니다.
matt 2

32

XCode6 베타 6부터 '동적'기능을 사용할 수 있습니다.

dynamic func timerTick() { .... }

이 UILocalizedIndexedCollation.currentCollation ()를 사용하려고 내 문제 해결
DogCoffee

이것은 NSObject에서 전체 클래스를 상속하는 것보다 더 나은 접근 방식입니다.
bobics 2015 년

8

let encodedArchive = NSKeyedArchiver.archivedDataWithRootObject(archive) as NSData아카이브가 사용자 지정 클래스의 배열 인 곳 을 사용하려고하면 비슷한 오류가 발생했습니다 . 나는 그 커스텀 클래스를 NSObject와 NSCoding의 서브 클래스로 선언하는 것이 트릭임을 발견했다. NSCoding 프로토콜을 준수하려면 몇 줄이 더 필요하므로 다음과 같이 시작해야합니다.

class Person: NSObject, NSCoding {
  init() {
    super.init()
  }

  func encodeWithCoder(_aCoder: NSCoder) {   }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.