在Swift中,你可以打电话
let bundle = NSBundle(forClass: self.dynamicType)
在任何类中获取当前的包。如果你NSBundle.mainBundle()
这将无法获得正确的捆绑,例如运行单元测试。
那么如何获得Swift struct
的当前捆绑?
这里最好的解决方案取决于你需要捆绑的东西。
是否要查找仅存在于特定应用程序,框架或扩展包中的资源,这些资源在您编写的代码运行时已知会被加载?在这种情况下,您可能希望使用init(identifier:)
而不是动态查找定义特定类型的包。
注意“跟随类型”捆绑包查找。例如,如果框架类Foo
使用NSBundle(forClass: self.dynamicType)
加载资源,那么加载该框架的应用程序定义的Foo
的子类将最终查找应用程序包而不是框架包。
如果确实需要对结构(或枚举)进行“跟随类型”捆绑查找,则可能有用的一种解决方法是将类定义为子类型:
struct Foo {
class Bar {}
static var fooBundle: NSBundle { return NSBundle(forClass: Foo.Bar.self) }
}
注意这里没有任何动态,因为没有必要 - 每个Foo
来自相同的类型定义(因为结构不能继承),所以它的静态类型匹配其动态类型。
(不可否认,可以处理结构,枚举和协议的NSBundle(forType:)
可能会成为一个nice feature request。虽然我认为让它处理扩展和一切都可能很棘手......)
针对Swift 3.0+进行了更新:
struct Foo {
class Bar {}
static var fooBundle: Bundle { return Bundle(for: Foo.Bar.self) }
}
extension Bundle {
static var current: Bundle {
class __ { }
return Bundle(for: __.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的子集,在这种情况下只有类可以从它继承。
如果类型的实例很小并且通常是短暂的或通常嵌入在其他对象中,请尝试使用结构。对于其他情况使用类。
通常我只在以下情况下使用结构: