2016-08-28 2 views
3

Я получаю сообщение об ошибке «непризнанный селектор, отправленный в экземпляр», когда в одной структуре Swift я пытаюсь вызвать функцию, которая определяется как расширение для UIView в другой структуре Swift. Он очень похож на проблему, которая решается путем передачи флага -ObjC в компоновщик (https://developer.apple.com/library/ios/qa/qa1490/_index.html) и проблема, возникающая при распространении общего в каркасе (Swift Framework does not include symbols from extensions to generic structs). К сожалению, моя проблема, как представляется, отличаются тем, что:Может ли Swift использовать базовые расширения класса Swift?

  1. И структура, которая определяет расширение и рамки, которые пытаются использовать это написано в Swift.
  2. Оба фреймворка - это «Cocoa Touch Frameworks», а не статические библиотеки.
  3. Расширяемый класс: UIView, а не общий.
  4. Добавление -ObjC или -all_load для всех задействованных целей не устранило проблему.

Контекст в том, что я добавил в проект iOS рамочную цель размещения классов IBDesignable. Название основного проекта - «Vital», а название структуры - «VitalDesignables». Я добавил еще одну фреймворк под названием «VitalKit», в которой содержится код, на который зависят как Vital, так и VitalDesignables. VitalKit определяет эту функцию для загрузки представления из nib, класс в VitalDesignables пытается вызвать его в init (frame: CGRect), а IB не может загрузить этот класс, когда я ссылаюсь на него в раскадровке.

public extension UIView { 
    public func loadViewFromNib(nibName: String) -> UIView { 
     let bundle = NSBundle(forClass: self.dynamicType) 
     let nib = UINib(nibName: nibName, bundle: bundle) 
     let topLevelItems = nib.instantiateWithOwner(self, options: nil) 
     let topLevelViews = topLevelItems.filter() { $0.isKindOfClass(UIView) } 
     precondition(topLevelViews.count == 1, 
        "There must be only one top-level view") 

     return topLevelViews.first as! UIView 
    } 
} 
+0

Никогда не пробовал, но было бы странно, если бы вы не могли. Вам придется импортировать фреймворк в свою структуру. – ntoonio

ответ

2

Обязательно импортировать структуру, которая содержит расширение в рамках, которые не содержат его:

Framework2:

public extension UIView { 
    public func loadViewFromNib(nibName: String) -> UIView { 
     let bundle = NSBundle(forClass: self.dynamicType) 
     let nib = UINib(nibName: nibName, bundle: bundle) 
     let topLevelItems = nib.instantiateWithOwner(self, options: nil) 
     let topLevelViews = topLevelItems.filter() { $0.isKindOfClass(UIView) } 
     precondition(topLevelViews.count == 1, 
        "There must be only one top-level view") 

     return topLevelViews.first as! UIView 
    } 
} 

Framework1:

import Framework2 

class ViewController : UIViewController 
{ 
    override func viewDidLoad() { 
     super.viewDidLoad() 

     self.view!.loadViewFromNib("mynib") 
    } 
} 

Запомнить, расширение должно быть общедоступным. (Изменить: теперь установлено значение open), я полагаю, что по умолчанию установлено значение internal, поэтому это означает, что он может быть замечен в текущем модуле, но внешние модули не смогут это увидеть.

0

Вы не можете отправлять фреймворки с помощью фреймворков, поэтому, если Framework2 reference Framework отлично подходит для целей компиляции.

Убедитесь, что цель iOS приложения включает в себя как Framework1, так и Framework1 встроенные двоичные файлы, иначе они не будут компилироваться .. см. Снимок экрана.

Embed framework

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