Eine seltsame Sache, die mich stolpert. Fühlt sich an, als gäbe es ein einfaches "In Swift 2 machen wir immer (oder nie) dieses", dass ich vermisse, aber ich kann es nicht sehen.Swift, Singletons, Variablen, die Funktionen darstellen
ich eine Gehirn-Klasse, gemeint als Singleton verwendet werden:
class Brain: NSObject {
static var sharedInstance : Brain?
var languageLoadedAndReadyFunction = languageLoadedAndReadyImplementation
init() {
NSNotificationCenter.defaultCenter().addObserver(self,
selector: "languageLoadedAndReady",
name: Notifications.LanguageLoadedAndReady,
object: nil)
}
func languageLoadedAndReadyImplementation() {
print("Got language Ready notification")
}
func languageLoadedAndReady() {
self.languageLoadedAndReadyFunction(self)()
}
class func get() -> Brain! {
return sharedInstance
}
//...
class func reset() {
sharedInstance = Brain()
}
deinit() {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
}
In meinem Unit-Test für Gehirn:
func testBrainRegisterForNotificationWhenWakingUp() {
let expectation = expectationWithDescription("Function should be called when the notification is received")
var brain = Brain.get()
brain.languageLoadedAndReadyFunction = {brain ->() ->() in
{
expectation.fulfill()
Brain.reset() // <-- this sets sharedInstance to a new Brain
}
}
brain.startUp() // <-- this causes the languageLoadedAndReady event to arrive at the brain
waitForExpectationsWithTimeout(5) {
error in
if let error = error {
print("Error: \(error.localizedDescription)")
}
}
}
The way I benötigt, um die Funktion als „Gehirn definieren ->() ->() "fühlt sich schwerfällig an, aber es scheint ein Leckerbissen zu sein. Es ließ mich sehen, wann die Benachrichtigung eintraf, also konnte ich per Test verifizieren, dass wir uns korrekt verhalten. Die Deinit() - Methode wird aufgerufen, nachdem das Gehirn zurückgesetzt wurde, und zeigt mir an, dass das alte Gehirn aus dem Gedächtnis entfernt wird.
Heute bin ich einige neue Tests für TranslatorTests.swift Schreiben:
func testTranslatorCanTranslate() {
let expectation = expectationWithDescription("Function should be called when the notification is received2")
var brain = Brain.get()
brain.languageLoadedAndReadyFunction = {brain ->() ->() in
{
expectation.fulfill()
Brain.reset()
print("first TranslatorTests")
}
}
brain.startUp() // <-- 'brain' is different here than in BrainTests.swift, causes
// the closure in BrainTests.swift to be called.
waitForExpectationsWithTimeout(5) {
error in
if let error = error {
print("Error: \(error.localizedDescription)")
}
}
translator.setActiveLanguage("en")
let resultString = translator.translate("about_title")
XCTAssertEqual(resultString, "About")
}
func testTranslatorCanTranslateSecondWord() {
let expectation = expectationWithDescription("Function should be called when the notification is received3")
let brain = Brain.get()
brain.languageLoadedAndReadyFunction = {brain ->() ->() in
{
expectation.fulfill()
Brain.reset()
print("second TranslatorTests")
}
}
brain.startUp() // <-- 'brain' is different here than in BrainTests.swift, causes
// the closure in BrainTests.swift to be called.
waitForExpectationsWithTimeout(5) {
error in
if let error = error {
print("Error: \(error.localizedDescription)")
}
}
translator.setActiveLanguage("en")
let resultString = translator.translate("actmon_ready")
XCTAssertEqual(resultString, "Ready to upload")
}
Wenn ich die Tests ausführen, bekomme ich die bizarrsten Fehler: der Verschluss in BrainTests.swift aufgerufen wird, wenn die TranslatorTests. swift wird ausgeführt. Dadurch wird die expectation.fullfill() -Methode ein zweites Mal aufgerufen, was zu einem Absturz führt.
Übrigens gibt es innerhalb der Schließung kein "Selbst", aber wenn ich eine Ebene in der Aufrufliste nach oben gehe, bezieht sich das "Selbst" auf die vorherige Instanz des Gehirns. Das führt mich zu der Annahme, dass das Gehirn ->() ->() -Syntax das Problem ist.
Dies schreckt mich. Das "Gehirn" hat vor jeder Schließung eine andere Adresse, was mir anzeigt, dass es sich um eine andere Instanz handelt. In der Tat, das alte Gehirn wurde von diesem Punkt entweiht, wie könnte es also heißen?
Ich hätte gedacht, dass die Zuweisung an die Variable für eine Instanz bedeuten würde, dass wir der Schließung eine neue Funktion geben, die für diese Instanz ausgeführt werden soll.
Kann mir das jemand erklären? Bitte benutze kleine Worte, ich fühle mich etwas weniger intelligent als beim Schreiben dieses Codes.