Swift Framework не включает символы из расширений в общие структуры
У меня возникли проблемы с привязкой моей структуры к коду, который использует эту инфраструктуру. В частности, компоновщик не может найти символы для расширений для генерических структур.
Это то, что одно из расширений выглядит как Необязательно:
extension Optional { /// Unwrap the value returning 'defaultValue' if the value is currently nil func or(defaultValue: T) -> T { switch(self) { case .None: return defaultValue case .Some(let value): return value } } }
Этот метод отлично работает на игровой площадке или в приложении, если код скомпилирован в основной части приложения. Однако, когда я пытаюсь скомпилировать это в Framework, приложения (и даже тесты для фреймворка) вызывают следующую ошибку компоновщика:
- Как обращаться с несколькими местоположениями по одному и тому же адресу и сгруппировать их?
- Где найти четкое объяснение относительно быстрого предупреждения (UIAlertController)?
- Dyld фатальный в Xcode 7.0 beta
- Печать NSError от NSLog всегда вызывает EXE_BAD_ACCESS
- Программное задание имени tabBarItem в Swift
Неопределенные символы для архитектуры i386: «__TFSq2orU__fGSqQ__FQQ», на которые ссылаются: __TFC18SwiftPlusPlusTests27Optional_SwiftPlusPlusTests13testOrWithNilfS0_FT_T_ in Optional + SwiftPlusPlusTests.o
Аналогичные методы, такие как следующий, ссылка прекрасная (заметьте, это не на общем)
extension String { /// Returns a string by repeating it 'times' times func repeat(times: Int) -> String { var result = "" for i in 0..times { result += self } return result } }
В моем репозитории есть два других расширения: gigub : SwiftPlusPlus, которые также не связаны (как с общими строками). Вы будете воспроизводить ошибки, если вы вытащили последнюю фиксацию, построили фреймворк, а затем попытаетесь выполнить модульные тесты.
До сих пор я пытался запустить «строки» на выведенных фреймворках и промежуточных файлах, и я не вижу символов для этих расширений, но вижу символы для расширения метода repeat
на String
. Таким образом, он даже не собирается компилировать их в библиотеку.
Кто-нибудь знает, почему символы не определены в рамках?
редактировать
- Вот ссылка на мое дополнительное расширение
- Вот ссылка на тестовый файл, который вызывает ошибку компоновщика при попытке скомпилировать тестовый объект
- Высота UICollectionView не динамически увеличивается с использованием внутри UIScrollView
- Преобразование CGFloat в NSNumber в Swift
- parser.parse () в Swift приводит к EXC_BAD_ACCESS
- Обрезать изображение снизу программно
- Удалить элемент в массиве без жесткого кодирования индекса? в Свифт
- MKAnnotation Swift
- Scenekit - convertTransform поворотного под-subNode на основе мировых осей
- Как создать экземпляр контроллера просмотра с контроллером tab и nav для глубокой привязки?
Я опубликовал на форумах разработчиков Apple, и сотрудник Apple ответил, что это известная ошибка.
Похоже, что компилятор неправильно использует искаженные имена символов в общих расширениях, когда они живут в другой структуре.
Если вы ищете временное исправление, вы можете обернуть расширение в методе класса:
// In your framework public class OptionalOperator { public class func or<T>(optional:Optional<T>,defaultValue:T) ->T { return optional.or(defaultValue) } } // Outside the framework var maybeText:String? let text = OptionalOperator.or(maybeText, defaultValue: "Apple, please fix this")
Разумеется, это не идеальное решение, и он поражает цель расширений. Поэтому, если вы планируете часто вызывать этот метод, мы можем перегрузить / определить оператор .
// In your framework infix operator
{} public func
<T>(left:Optional<T>, right:T) -> T { return left.or(right) } // Outside the framework var maybeText:String? let text = maybeText
"Apple, please fix this"
В моем случае у меня есть несколько приложений, использующих фреймворк, поэтому я хочу сохранить реализацию метода внутри фреймворка. Однако перегрузка оператора (или просто использование глобальной функции) была бы неудобной, поэтому мне нужно перейти с первой опцией до тех пор, пока эта ошибка не будет исправлена.
Надеюсь это поможет.
ОБНОВИТЬ
Смешно, что у Свифта уже есть оператор для этого ( ?? ).
var maybeText:String? let text = maybeText ?? "Nice!"
Это называется – Nil Coalescing Operator