2017-07-16 6 views
2

Ich habe einiges Projekt, wo ich praktisch Architektur geschaffen für meine brauchen und alles war in Ordnung, bis ich mysteriöse Abstürze mit EXC_BAD_ACCESS zur Laufzeit auftreten. Ich stellte here die kleinste Code, der das Problem darstellt, und hier ist die Erklärung:Mysterious EXC_BAD_ACCESS in einfachen Code

einige und ein anderer Stellen, die Kind erste lautet:

protocol Base { 

    static var key: String { get } 
} 

protocol BaseChild: Base { 

} 

Und hier einige einfache Implementierung:

struct ChildEntity: BaseChild { 

    static var key: String { 
     return "key" 
    } 
} 

Dann habe ich eine Klasse, die mit solchen Einheiten funktioniert:

class Worker { 

    static var defaultWorker: Worker? // will explain later 

    func work<T: Base>(entity: T) { 
     print(T.key) 
    } 
} 

Und ich habe auch einige Unterklassen von Worker:

class ChildWorker: Worker { 

    override func work<T: BaseChild>(entity: T) { 
     print(T.key) 
    } 
} 

So weit so gut. Dann habe ich statisch defaultWorker var meine Worker Klasse hinzugefügt Zugriff auf meine Standard-Arbeiter zu erleichtern, dies ermöglicht es mir, eine Erweiterung für mein Base Protokoll zu schaffen, die mit meiner defaultWorker arbeiten:

extension Base { 

    func work() { 
     Worker.defaultWorker?.work(entity: self) 
    } 
} 

aber dies erzeugt EXC_BAD_ACCESS zur Laufzeit . Hier ist einfach Nutzung:

class Test { 

    static func run() { 
     let object = ChildEntity() 
     let worker = ChildWorker() 
     worker.work(entity: object) // OK here 

     Worker.defaultWorker = worker 
     object.work() // EXC_BAD_ACCESS here 
    } 
} 

Getestet habe ich diese auf beiden Xcode 8 und 9 Xcode mit Swift 3 und Swift 4. Bitte helfen Sie mir, dieses Problem zu lösen

+0

Versuchen Sie 'object.work' (entfernen'() ') ... oder lassen Sie das und tun' Test.run' –

+0

@ l'L ich danke Ihnen, aber was ist der Sinn, das zu tun? Ich kann das gleiche Ergebnis erzielen, wenn ich einfach diese Zeile auszeichne. Ich meine, das Entfernen von Klammern wird aufhören, meine Funktion auszuführen, aber ich brauche es zu arbeiten – Azat

+0

Es ist hilfreich, was passiert ... der Fehler ist in der Zeile 'Worker.defaultWorker? .work (Entität: selbst)' –

Antwort

0

Ich frage mich, warum Sie func work<T: Base>(entity: T) zu override func work<T: BaseChild >(entity: T) außer Kraft setzen?

Ist das nicht soll override func work<T: Base>(entity: T) sein?

+0

nennen wollte ich, dass mein Kind Arbeiter mit' BaseChild' nur funktionieren würde, Instanzen, also habe ich versucht, mögliche Aufrufe auf der Compiler-Ebene einzuschränken. Aber wenn ich das mache, heißt es, dass ich das Schlüsselwort "override" vermisse und der Compiler ist glücklich – Azat