Der vollständige Testfall unten soll demonstrieren: Ein Selektor wird, obwohl er an zwei Stellen gleich spezifiziert ist, anders ausgeführt: Entweder wird er an der Klasse oder am Objekt ausgeführt. (Ich verstehe, dass eine statische Methode und eine Objektmethode denselben Namen haben können, aber es gibt nur einen darunter.) Ob der Empfänger Klasse oder Objekt ist, hängt davon ab, wo das "gleiche" selector zu NSNotificationCenter
gemacht wird, entweder Klasse Kontext oder in Verfahren Kontext:Ist das Ziel von #selector() abhängig vom Kontext von `addObserver` (Klasse vs Objekt)?
- eine statische Methode, den Anruf zu
addObserver
hat oder - eine Objektmethode hat den Anruf
addObserver
während die Anrufe ansonsten identisch sind. Wenn der identische Aufruf in einer statischen Methode auftritt, versucht das System, wenn die Benachrichtigung später verarbeitet wird, den Selektor der Klasse und nicht das Objekt aufzurufen. Die Klasse hat es nicht. Der Code kompiliert gut mit der neuen (in 2.2) Syntax. Ist dieses Ergebnis zu erwarten?
import XCTest
import class Foundation.NSNotificationCenter // for emphasis
class SelectorTests: XCTestCase {
static let NotificationName = "OneTwoThreeNotification"
override func setUp() {
super.setUp()
}
override func tearDown() {
NSNotificationCenter.defaultCenter().removeObserver(self)
super.tearDown()
}
func addObserverForTestNormal() { // <- HERE
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: #selector(SelectorTests.myMethod(_:)), // <- HERE
name: SelectorTests.NotificationName,
object: nil)
}
func testNormal() {
self.addObserverForTestNormal()
NSNotificationCenter.defaultCenter().postNotificationName(
SelectorTests.NotificationName,
object: self)
}
static func addObserverForTestStatic() { // <- HERE
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: #selector(SelectorTests.myMethod(_:)), // <- HERE
name: SelectorTests.NotificationName,
object: nil)
}
func testStatic() {
SelectorTests.addObserverForTestStatic()
NSNotificationCenter.defaultCenter().postNotificationName(
SelectorTests.NotificationName,
object: self)
}
func myMethod(x : Int) {
XCTAssert(true)
}
}
Ein Test ist erfolgreich, der andere schlägt fehl. Der Kern des Stack-Trace und die Nachricht ist
„+ [KuckuckTests.SelectorTests MyMethod:]: Unbekannter Selektor gesendet Klasse
Ist diese Spaltung, dh Klasse oder ein Objekt‚abgeleitet‘von addObserver
- ? Zusammenhang so offensichtlich zu alt Objective-C Hände, dass sie mit #selector
erwähnen in diesem Fall nicht wert ist, könnten Sie eine Dokumentation hinweisen
bearbeiten: habe gerade bemerkt, dass self
in der inv statische Funktion ocation von addObserver
bezieht sich vielleicht auf die Klasse, nicht auf irgendein Objekt. Das macht den Effekt etwas plausibel, und schlägt vor, dass Programmierer wissen sollten, wofür überladene Namen stehen ...