Xcode видит только некоторые из подобных расширений вложенного класса, написанные в отдельных файлах

Я пытаюсь сделать свой код как можно более читабельным, сохраняя методы и файлы как можно более короткими и используя вложенные классы для пространства имен. Работает нормально, за исключением действительно странного момента.

У меня есть класс, используемый для пространства имен.

class Space { }

Все классы, используемые в нем, реализованы в своих собственных файлах как расширения.

extension Space {
    class SomeClass {
       // implementation
    }
}

Один из этих SomeClasses имеет несколько довольно сложных инициализаторов, поэтому я разделил их на отдельные файлы и реализовал следующим образом:

extension Space.SomeClass {
    convenience init(fromSomeSource source: SourceClass) {
        self.init()
        // other implementation
    }
}

Проблема в том, что некоторые из этих файлов работают просто отлично, но некоторые из них выдают 'SomeClass' is not a member type of 'Space', и я не знаю почему.

Все они довольно похожи. Единственная разница заключается в реализации самого инициализатора. Все файлы хранятся в одном месте, и я понятия не имею, почему некоторые из них работают нормально, а некоторые нет.

Я пытался переместить код из нерабочих файлов в файлы, которые нормально работают и работают — Xcode соглашается видеть код и ничего против этого не говорит. Но когда тот же самый код лежит в собственном файле — Xcode или компилятор не хотят понимать, что SomeClass действительно является членом Space.

Пробовал чистить сборку, включая ручной сброс папки ~/Library/Developer/Xcode/DerivedData. Ничего не помогает.

Конечно, я могу поместить все это в один файл, и он будет работать нормально, но почему он такой придирчивый в моем случае?


Я попытался создать новый файл и переместить туда все содержимое одного из плохих файлов. Это работает, но только с определенными именами файлов. Некоторые имена снова дают ту же ошибку, но кажется, что если имя совершенно новое и не похоже ни на одно из существующих - оно работает. Магия?


person Denis Kim    schedule 19.12.2015    source источник
comment
Вы пишете: Разница только в реализации самого инициализатора. В чем разница? Попробуйте изолировать разницу и показать нам, что происходит в вашем коде, включая сообщения компилятора.   -  person user3441734    schedule 20.12.2015
comment
@user3441734 user3441734 Разница в том, что у них есть разные типы объектов в качестве аргументов для инициализатора, поэтому с каждым типом можно обращаться по-своему. Например, в одном случае я помещаю соответствующее свойство в класс без обработки, в другом случае я каким-то образом меняю какую-то строку. Но проблема в том, что сам код работает просто отлично. Я могу поместить его в другой файл, и он будет работать. Так что проблема где-то в том, где я храню код, в каком файле. Это важно. Единственное сообщение, которое я получаю от Xcode, это то, о котором я упоминал: 'SomeClass' is not a member type of 'Space'   -  person Denis Kim    schedule 20.12.2015


Ответы (1)


Я столкнулся с подобной проблемой, похоже, что компилятор пытается обработать файл, в котором вы расширяете вложенный класс, до того, в котором он определен. Поэтому у вас есть эта ошибка, говорящая о том, что у этого Space нет члена SomeClass.

Решение, которое я нашел, состоит в том, чтобы перейти к вашим целевым настройкам, открыть Build Phases.

введите здесь описание изображения

Там, в разделе Compile Sources, вы должны поместить файл, в котором вы определяете файлы вложенного класса выше, где вы его расширяете.


Это решение, кажется, даже хорошо сочетается с вашим наблюдением, что когда вы воссоздаете файл, он иногда компилируется, потому что, когда вы воссоздаете файл, его позиция в Compile Sources изменяется.

person Nikita Kukushkin    schedule 12.04.2016
comment
Спасибо, Никита! - person Denis Kim; 15.04.2016