Cocoa - loadNibNamed:owner:topLevelObjects:来自已加载的包

时间:2014-01-15 00:35:41

标签: objective-c cocoa nib nsbundle

在基于文档的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无关。

我将如何实现这一目标?有没有办法找到“当前”包(插件类来自的包,可以这么说)?

感谢。

1 个答案:

答案 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]]