Как получить комплект для структуры?

23

В Swift вы можете позвонить

let bundle = NSBundle(forClass: self.dynamicType)

в любом классе и получить текущий пакет. Если вы NSBundle.mainBundle(), это приведет к сбою в правильном комплекте, например, при выполнении модульных тестов.

Итак, как вы можете получить текущий пакет для Swift struct?

  • 0
    Также ищу ответ на этот вопрос. У меня есть определение класса-заполнителя и расширение NSBundle , поэтому я могу продолжать работать, пока не будет найдено правильное решение.
Теги:
struct
nsbundle

4 ответа

21
Лучший ответ

Лучшее решение здесь зависит от того, для чего вам нужен комплект.

Нужно ли искать ресурсы, которые существуют только в определенном пакете приложений, фреймворков или расширений, которые, как известно, загружаются при запуске кода, который вы пишете? В этом случае вы можете использовать init(identifier:) вместо динамического поиска пакета, который определяет определенный тип.

Остерегайтесь "следует за поиском пакетов". Например, если класс framework Foo использует NSBundle(forClass: self.dynamicType) для загрузки ресурса, подкласс Foo, определяемый приложением, загружающим эту структуру, в конечном итоге будет выглядеть в комплекте приложений вместо пакета структуры.

Если вам нужно "следовать за поиском пакетов" для структуры (или перечисления), одним из способов, которые могут оказаться полезными, является определение класса как подтипа:

struct Foo {
     class Bar {}
     static var fooBundle: NSBundle { return NSBundle(forClass: Foo.Bar.self) }
}

Обратите внимание, что здесь нет ничего динамического, потому что ничего не должно быть - каждый Foo поступает из одного и того же определения типа (потому что structs не может наследовать), поэтому его статический тип соответствует его динамическому типу.

(По общему признанию, NSBundle(forType:), который мог бы обрабатывать структуры, перечисления и протоколы, мог бы сделать приятный запрос функции. Хотя я думаю, что было бы сложно сделать это обрабатывать расширения и все...)

  • 0
    будет работать "static let fooBundle = Bundle (for: Foo.Bar.self)"? @rickster
  • 1
    Да, это выглядит работоспособным. (Мой первоначальный ответ предшествует NSBundle что NSBundle был переименован в Bundle для Swift.) Однако не стесняйтесь проверять его.
5

Обновлено для Swift 3. 0+:

struct Foo {
     class Bar {}
     static var fooBundle: Bundle { return Bundle(for: Foo.Bar.self) }
}
0
internal struct InternalConstants {
    private class EmptyClass {}
    static let bundle = Bundle(for: InternalConstants.EmptyClass.self)
}

Другое потенциальное решение (менее элегантное):

internal struct InternalConstants {
    internal static let bundle = Bundle(identifier: "com.hello.world")!
}
-1

Вы не можете взять NSBundle из структуры, потому что структуры не могут наследовать.

Класс NSBundle ожидает всегда одного класса, который является подмножеством NSObject, в этом случае только классы могут наследовать его.

Попробуйте использовать структуру, если экземпляры типа являются малыми и обычно недолговечными или обычно внедряются в другие объекты. для других случаев используйте класс.

Обычно я использую только структуры в случае:

  • Модели и объекты объектов
  • Неизменяемость (не для всех, но в большинстве случаев)
  • Размер экземпляра не более 16 байт.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню