Проблема заключается в использовании self
внутри хранимого свойства myComponent
.Как правило, не разрешается раздавать self
до завершения инициализации инициализатора всего объекта.Поэтому ваша проблема не имеет ничего общего с протоколами или расширениями.Более просто:
import Foundation
class Component {
init(requiresAnObjectofTypeMyClass:MyClass) {
}
}
// I need the class to be a NSObject for unrelated requirements
class MyClass : NSObject {
// I force the compilation, but it then breaks apart at runtime anyway
private let myComponent =
Component(requiresAnObjectofTypeMyClass : self as! MyClass)
}
let m = MyClass()
также дает сбой.
Если вы пропустите подкласс NSObject
, вы получите ошибку компилятора:
использование неразрешенного идентификатораКомпонент 'self' (требуетAnObjectofTypeMyClass: self as! MyClass)
Это показывает проблему: вы не должны использовать self
здесь.Я думаю, что это просто ошибка XCode;Xcode, кажется, игнорирует синтаксическую ошибку при создании подкласса NSObject
.Приведение as! MyClass
также является подсказкой о том, что мы ищем странный обходной путь, который, в конце концов, ставит Xcode на колени и вызывает сбой во время выполнения.
Чтобы обойти это, вы можете создать свойство lazy, которое будетбудет оцениваться после процесса инициализации и, следовательно, позволит self
быть переданным в Component
инициализатор:
private(set) lazy var myComponent = Component(requiresAnObjectofTypeMyClass:self)
Здесь вам также не понадобится приведение.К сожалению, lazy let
не разрешен в swift (и никто не знает почему), поэтому private(set)
близок к его семантике.
Этот код легко перенести в пример протокола.