В Swift вы можете позвонить
let bundle = NSBundle(forClass: self.dynamicType)
в любом классе и получить текущий пакет. Если вы NSBundle.mainBundle()
, это приведет к сбою в правильном комплекте, например, при выполнении модульных тестов.
Итак, как вы можете получить текущий пакет для Swift struct
?
Лучшее решение здесь зависит от того, для чего вам нужен комплект.
Нужно ли искать ресурсы, которые существуют только в определенном пакете приложений, фреймворков или расширений, которые, как известно, загружаются при запуске кода, который вы пишете? В этом случае вы можете использовать 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:)
, который мог бы обрабатывать структуры, перечисления и протоколы, мог бы сделать приятный запрос функции. Хотя я думаю, что было бы сложно сделать это обрабатывать расширения и все...)
NSBundle
что NSBundle
был переименован в Bundle
для Swift.) Однако не стесняйтесь проверять его.
Обновлено для Swift 3. 0+:
struct Foo {
class Bar {}
static var fooBundle: Bundle { return Bundle(for: Foo.Bar.self) }
}
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")!
}
Вы не можете взять NSBundle из структуры, потому что структуры не могут наследовать.
Класс NSBundle ожидает всегда одного класса, который является подмножеством NSObject, в этом случае только классы могут наследовать его.
Попробуйте использовать структуру, если экземпляры типа являются малыми и обычно недолговечными или обычно внедряются в другие объекты. для других случаев используйте класс.
Обычно я использую только структуры в случае:
NSBundle
, поэтому я могу продолжать работать, пока не будет найдено правильное решение.