2016-01-16 4 views
0

Я потратил некоторое время на то, чтобы понять это. Этот код авария:Быстрое сбой при литье подкласса NSObject в протокол non-objc

public protocol FourLeggedAnimal: AnyObject { 

} 

public class Animal: NSObject { 

} 

public class Dog: Animal, FourLeggedAnimal { 

} 


public class AnimalProperty<Kind: Animal>: NSObject { 

    let animal: Kind 

    public init(animal: Kind) { 
     self.animal = animal 
    } 

} 

public class FourLeggedAnimalProperty<Kind: Animal>: AnimalProperty<Kind>, NSTextFieldDelegate { 

    public override init(animal: Kind) { 
     /// Since we cannot express in Swift that the Kind should be an Animal 
     /// subclass confirming to a particular protocol, we use a force-cast 
     /// which is not a pretty solution, but there aren't any options. 

     /// And this crashes. 
     let fourLeggedAnimal = animal as! FourLeggedAnimal 
     print(fourLeggedAnimal) 

     super.init(animal: animal) 
    } 

} 


let dog = Dog() 
let property = FourLeggedAnimalProperty(animal: dog) 

Кодовый сбой в getGenericPattern() функции библиотеки Свифта при попытке C собаки к протоколу FourLeggedAnimal в intializer.

Примечания:

  • Правильный путь должен быть объявить дженерики, как <Kind: Animal, FourLeggedAnimal>, однако, когда вы сделаете это, вы не можете назвать init(animal:) инициализатору с Dog, несмотря на то, что это Animal и FourLeggedAnimal.
  • Приложение вылетает, даже если вы используете soft-cast, т. Е. Это не ошибка, это на самом деле ошибка во время выполнения Swift.

ответ

0

Решение состоит в том, чтобы либо объявить FourLeggedAnimal, как @objc, или сделать Animalне наследовать от NSObject.

+0

К сожалению, объявление как @objc является несовершенным решением, если вам нужно работать с быстрыми конкретными функциями, такими как перечисления, а не наследовать от nsobject, иногда невозможно, когда речь идет о многих встроенных библиотеках. Эта ошибка/недостаток функции делает использование протокола крайне расстраивающим. –

+0

Согласовано. Тем не менее, мне потребовалось некоторое время, чтобы не привести к сбою моего кода, поэтому я опубликовал это полу-решение для тех, кто имеет такую ​​же проблему. Я, конечно же, сообщил об этой проблеме и Apple ... Ну, с августа прошлого года я подал более 70 ошибок, связанных с Xcode и Swift ... –

Смежные вопросы