在基于文档的Cocoa应用程序中,我使用以下命令从外部包中实例化多个对象(插件):
- (NSMutableArray *)getPluginsOfType:(Class)type;
{
NSBundle *main = [NSBundle mainBundle];
NSArray *allPlugins = [main pathsForResourcesOfType:@"bundle" inDirectory:@"../PlugIns"];
NSMutableArray *availablePlugins = [NSMutableArray array];
for (NSString *path in allPlugins)
{
NSBundle *pluginBundle = [NSBundle bundleWithPath:path];
[pluginBundle load];
Class principalClass = [pluginBundle principalClass];
[availablePlugins addObject:principalClass];
}
return availablePlugins;
}
在每个文件中,在init上加载一个nib文件,它将根视图与我的插件类中的属性绑定在一起。在最小的插件类定义下面:
@interface Plugin
@property (strong) IBOutlet NSView *thePluginView;
@end
@implementation Plugin
- (instancetype)init
{
self = [super init];
if (self)
{
[NSBundle loadNibNamed:@"NibName" owner:self];
}
return self;
}
@end
虽然这很好用,但我想将上面的调用替换为NSBundle(因为它已被OS X 10.8+弃用),并将其替换为:
[[NSBundle mainBundle] loadNibNamed:@"NibName" owner:self topLevelObjects:nil];
但是,在这种情况下使用mainBundle自然无法在我的Plugin类中设置顶级对象引用,我怀疑mainBundle与Plugin的bundle无关。
我将如何实现这一目标?有没有办法找到“当前”包(插件类来自的包,可以这么说)?
感谢。
答案 0 :(得分:6)
我不清楚你究竟在问什么 - 你的应用程序包中没有的“加载类”来自哪里,你对“加载类”究竟是什么意思?
也许以下内容会有所帮助:
loadNibNamed:owner:topLevelObjects:
是一个实例方法,从实例表示的包中加载。
在您的示例中,您使用的实例是通过[NSBundle mainBundle]
获取的,因此从应用程序主包中加载了nib。
没有“当前捆绑”概念,但您可以获得表示其他捆绑包的NSBundle
实例,例如使用NSBundle
的类方法bundleWithURL
。因此,要从另一个bundle加载一个nib,首先创建一个引用该bundle的NSURL
,然后根据它创建一个NSBundle
,最后加载nib。
HTH
附录 - 问题更新后
来自弃用+loadNibName:owner:
方法的owner
描述:
如果此对象的类具有关联的包,则搜索该包以查找指定的nib文件;否则,此方法将在主捆绑中查找。
这是您在使用-loadNibNamed:owner:topLevelObjects:
时需要复制的内容。您需要的方法是NSBundle
的{{1}},它返回动态加载类的bundleForClass:
对象。
因此,在您的NSBundle
课程中,您应该能够找到使用Plugin
加载的包,然后在其上调用[NSBundle bundleForClass:[self class]]
。