2017-07-16 5 views
2

J'ai un projet où j'ai créé une architecture pratique pour mon besoin et tout allait bien jusqu'à ce que je rencontre des plantages mystérieux avec EXC_BAD_ACCESS à l'exécution. J'ai posté here le plus petit code qui représente la question et voici l'explication:Mystérieux EXC_BAD_ACCESS en code simple

Imaginez un peu et un autre qui est l'enfant de première:

protocol Base { 

    static var key: String { get } 
} 

protocol BaseChild: Base { 

} 

Et est une implémentation simple ici:

struct ChildEntity: BaseChild { 

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

Ensuite, j'ai une classe qui fonctionne avec de telles entités:

class Worker { 

    static var defaultWorker: Worker? // will explain later 

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

et moi avons aussi une sous-classe de Worker:

class ChildWorker: Worker { 

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

Jusqu'à présent, si bon. Ensuite, j'ai ajouté statique defaultWorker var ma Worker classe pour rendre l'accès à mon travail par défaut plus facile, cela me permet de créer une extension pour mon protocole Base qui travaillera avec mon defaultWorker:

extension Base { 

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

Cependant, cela génère EXC_BAD_ACCESS lors de l'exécution . Voici l'utilisation simple:

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 
    } 
} 

J'ai testé cette fois sur Xcode 8 et 9 avec Xcode Swift 3 et Swift 4. S'il vous plaît me aider à résoudre ce problème

+0

Essayez de faire 'object.work' (en supprimant'() ') ... ou en laissant cela et en faisant' Test.run' –

+0

@ l'L Je vous remercie, mais quel est le sens de faire cela? Je peux obtenir le même résultat en commentant simplement cette ligne. Je veux dire supprimer les parenthèses arrêtera d'exécuter ma fonction, mais j'en ai besoin pour fonctionner – Azat

+0

C'est utile pour ce qui se passe ... l'erreur est dans la ligne 'Worker.defaultWorker? .work (entity: self)' –

Répondre

0

Je me demande pourquoi vous substituez func work<T: Base>(entity: T) à override func work<T: BaseChild >(entity: T)?

N'est-ce pas supposé être override func work<T: Base>(entity: T)?

+0

Je voulais que mon enfant travaille uniquement avec' BaseChild' instances, donc j'ai essayé de réduire les appels possibles au niveau du compilateur. Mais quand je le fais, il est dit que je manque le mot-clé override et que le compilateur est content – Azat