- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在研究从 Swift 主机应用程序加载插件的概念证明。我能够在 Bundle 类上加载框架或 bundle , NSClassFromString
和 Bundle.principalClass
似乎工作正常,但我无法获得任何结果来自 Bundle.classNamed
函数。
这是我正在使用的代码:
for fullName in bundles {
print("Loading framework: \(fullName)")
if let bundle = Bundle(path: fullName), bundle.load(),
let name = fullName.split(separator: ".").first {
let typeNamed = bundle.classNamed(name + ".Plugin") as? NSObject.Type
let typeNS = NSClassFromString(name + ".Plugin") as? NSObject.Type
let typeNamedV2 = bundle.classNamed(name + ".PluginV2") as? NSObject.Type
let typeNSV2 = NSClassFromString(name + ".PluginV2") as? NSObject.Type
let typePrincipal = bundle.principalClass as? NSObject.Type
print("From bundle.classNamed: \(initPlugin(from: typeNamed)?.description ?? "")" )
print("From NSClassFromString: \(initPlugin(from: typeNS)?.description ?? "")" )
print("From bundle.classNamed: \(initPlugin(from: typeNamedV2)?.description ?? "")" )
print("From NSClassFromString: \(initPlugin(from: typeNSV2)?.description ?? "")" )
print("From bundle.principalClass: \(initPlugin(from: typePrincipal)?.description ?? "")" )
bundle.unload()
}
}
以下是输出:
Loading framework: One.framework
From bundle.classNamed:
From NSClassFromString: <One.Plugin: 0x102802060>
From bundle.classNamed:
From NSClassFromString: <One.PluginV2: 0x102802060>
From bundle.principalClass: <One.Plugin: 0x102801650>
Loading framework: CommonInterface.framework
From bundle.classNamed:
From NSClassFromString:
From bundle.classNamed:
From NSClassFromString:
From bundle.principalClass:
Loading framework: Bundle.bundle
From bundle.classNamed:
From NSClassFromString: <Bundle.Plugin: 0x102b08040>
From bundle.classNamed:
From NSClassFromString: <Bundle.PluginV2: 0x102b08f80>
From bundle.principalClass: <Bundle.Plugin: 0x102801ea0>
项目已配置为 Swift 5 和 Xcode 11 构建。
在这里您可以找到 POC 的完整源代码:
https://github.com/lechuckcaptain/SwiftPluginArchitectureExample
欢迎任何提示/反馈!
最佳答案
如果包是通过 Bundle(path:)
和一个相对加载的,那么 bundle.classNamed()
似乎不起作用小路。这是一个演示该问题的最小独立示例:
// This works:
let b1 = Bundle(path: "/System/Library/Frameworks/Foundation.framework")!
print(b1.load()) // true
let c1: AnyClass? = b1.classNamed("NSString")
print(c1 as Any) // Optional(NSString)
// This does not work
FileManager.default.changeCurrentDirectoryPath("/System/Library/Frameworks")
let b2 = Bundle(path: "Foundation.framework")!
print(b2.load()) // true
let c2: AnyClass? = b2.classNamed("NSString")
print(c2 as Any) // nil
对我来说这看起来像是一个错误。在您的情况下,快速解决方法是通过绝对路径加载 bundle :
if let bundle = Bundle(path: "\(path)/\(fullName)")
或者使用URL,以下是必要的修改:
// main.swift:
let pluginHost = PluginHost()
pluginHost.loadPlugins(at: Bundle.main.bundleURL)
// PluginHost.swift:
func loadPlugins(at url: URL) {
let fileManager = FileManager.default
let bundles = (try? fileManager.contentsOfDirectory(at: url, includingPropertiesForKeys: nil)
.filter { $0.pathExtension == "bundle"
|| $0.pathExtension == "framework"
}) ?? []
for bundleURL in bundles {
print("Loading framework: \(bundleURL)")
if let bundle = Bundle(url: bundleURL) {
let bundleName = bundleURL.deletingPathExtension().lastPathComponent
print("Name:", bundleName)
let typeNamed = bundle.classNamed(bundleName + ".Plugin") as? NSObject.Type
let typeNamedV2 = bundle.classNamed(bundleName + ".PluginV2") as? NSObject.Type
print("From bundle.classNamed: \(initPlugin(from: typeNamed)?.description ?? "")" )
print("From bundle.classNamed V2: \(initPlugin(from: typeNamedV2)?.description ?? "")" )
}
}
}
输出:
Start plugin loading
Loading framework: file:///.../One.framework/
Name: One
From bundle.classNamed: <One.Plugin: 0x100537f90>
From bundle.classNamed V2: <One.PluginV2: 0x1005388a0>
Loading framework: file:///.../CommonInterface.framework/
Name: CommonInterface
From bundle.classNamed:
From bundle.classNamed V2:
Loading framework: file:///.../Bundle.bundle/
Name: Bundle
From bundle.classNamed: <Bundle.Plugin: 0x10053a1d0>
From bundle.classNamed V2: <Bundle.PluginV2: 0x10053a1d0>
End plugin loading
Program ended with exit code: 0
备注:
如果您需要 protocol PluginInterface
中的 init()
方法(并实现所有插件中都需要一个 init()
)并像这样加载插件
if let cls = bundle.classNamed(bundleName + ".Plugin") as? PluginInterface.Type {
let plugin = cls.init()
plugin.doSomething()
}
if let cls = bundle.classNamed(bundleName + ".PluginV2") as? PluginInterface.Type {
let plugin = cls.init()
plugin.doSomething()
}
关于swift - Bundle.classNamed(_ 类名 : String) fails but NSClassFromString() work,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58113227/
我想创建一个依赖于给定模型实例的类的 Controller -(BaseController *)getControllerForModel:(Model *)model { Ba
这是我遇到的这个代码案例的问题: let entityTypeDico = ["entityTypeOne": arrayOne, "entityTypeOneTwo": arrayTwo,
使用 NSClassFromString 会有任何性能优势吗?特别是与从 header 导入类并初始化的标准方法相比时。 最佳答案 完全没有。如果有的话,NSClassFromString 比使用类的
我有一个类 X 和几个类 X1,X2,X3,X4 是 X 的后代 我有一个带有类名的 NSArray,我用它来迭代: _classnames = @[@"X1",@"X2",@"X3",@"X4"];
我正在尝试在 MonoTouch 中使用诸如以下 Objective-C 的代码: if (NSClassFromString(@"ADBannerView")) C# 中的等价物是什么? 基本上我想
NSClassFromString 在使用可选项时不起作用: var t = NSClassFromString("Swift.Optional") 有人能帮忙吗? 最佳答案 你是对的! NSClas
我目前正在尝试从 NSClassFromString(NSString *) 方法创建对象。 我希望能够实现的是以下... NSClassFromString(stringType) *pageCon
我正在尝试创建一个工厂类结构,其中我的抽象基类 PDObject 根据 NSDictionary 中传递给它的信息实例化一个正确的子类实例。这是我的 PDObject 初始化方法: - (id)i
我正在尝试编写一个函数,从我的字符串数组中加载一个特定的 View Controller >。然而,我很快就在这个概念上苦苦挣扎——我在 Objective - C 中实现了这一点。 static N
在下面的代码中,我使用 NSClassFromString 将 NSString“ColorFilter”转换为类名 ColorFilter。结果 ColorFilter 类似乎没有与同名导入语句中我
如果我在B.h文件中这样写: @interface A : NSObject @end @interface B : NSObject @end 然后 NSClassFromString(@"A")
我尝试动态调用某些 viewController/Feature 取决于他的名字。NSClassFromString (这种想法是由 Facebook 提出的)。对于来 self 的服务器的实例,我可
我有这个示例代码: let structType: String = "elearning_lesson" if let classType = NSClassFromString(struc
尽管 ListCell 是一个有效类,但以下代码打印出 nil。 var lCellClass : AnyClass! = NSClassFromString("ListCell"); println
我尝试使用从 NSClassFromString 创建的类来执行类方法,但我失败了。 在 Objective-C 中,这很容易: - (id)initWithStyle:(UITableViewCel
我的项目中有一个测试类,它在开发阶段就存在,但会为应用商店构建编译出来。 我在几本书中读到 NSClassFromString 可用于确定类是否存在,示例代码如下: if (NSClassFromSt
我想使用字符串来实例化一个类,但我遇到了问题。这就是我尝试做的: let aClass = NSClassFromString("MyApp.Outer.Inner") as! SomeProtoco
我进行动态类加载的原因是因为我正在创建一组可以在多个类似项目中使用的文件,所以执行#import 然后再进行正常实例化是行不通的。动态类允许我这样做,只要我可以在这些类中调用方法。每个项目在 pch
我目前正在装有 iOS 4.0 的 iPhone 3G 上测试一个应用程序。 我有以下代码来检查这个类是否可用。 if (NSClassFromString(@"CLGeocoder")) 在文档中它
尽管 ListCell 是一个有效类,但以下代码打印出 nil。 var lCellClass : AnyClass! = NSClassFromString("ListCell"); println
我是一名优秀的程序员,十分优秀!