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

Posted

技术标签:

【中文标题】Cocoa - loadNibNamed:owner:topLevelObjects: 来自加载的包【英文标题】:Cocoa - loadNibNamed:owner:topLevelObjects: from loaded bundle 【发布时间】:2014-01-15 00:35:41 【问题描述】:

在基于文档的 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 文件,它将根视图与我的插件类中的一个属性绑定。下面是一个最小的 Plugin 类定义:

@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 自然无法在我的插件类中设置***对象引用,我怀疑是因为 mainBundle 与插件的包无关。

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

谢谢。

【问题讨论】:

【参考方案1】:

我不清楚您到底在问什么 - 不在您的应用程序包中的“加载类”来自哪里,“加载类”到底是什么意思?

也许以下会有所帮助:

loadNibNamed:owner:topLevelObjects: 是一个实例方法,从该实例所代表的包中加载。

在您的示例中,您使用的实例是通过 [NSBundle mainBundle] 获得的,因此 nib 是从应用程序主包中加载的。

没有“当前捆绑包”的概念,但您可以获得代表其他捆绑包的NSBundle 实例,例如使用NSBundle 的类方法bundleWithURL。因此,要从不同的包加载 nib,首先创建一个引用该包的 NSURL,然后基于此创建一个 NSBundle,最后加载 nib。

HTH

附录 - 问题更新后

来自已弃用的+loadNibName:owner: 方法对owner 的描述:

如果该对象的类有关联的包,则在该包中搜索指定的 nib 文件;否则,此方法会在主包中查找。

这是您在使用-loadNibNamed:owner:topLevelObjects: 时需要复制的内容。你需要的方法是NSBundlebundleForClass:,它返回动态加载类的NSBundle对象。

因此,在您的 Plugin 类中,您应该能够找到使用 [NSBundle bundleForClass:[self class]] 加载它的包,然后调用 -loadNibNamed:owner:topLevelObjects:

【讨论】:

感谢您的回答。我扩展了问题以使其更具体。 @user2311023 - 查看更新问题的更新答案。 老方法的深刻见解!效果很好,非常感谢。

以上是关于Cocoa - loadNibNamed:owner:topLevelObjects: 来自加载的包的主要内容,如果未能解决你的问题,请参考以下文章

静态 cocoa/cocoa-touch 库应该基于啥样的 SDK?

Cocoa设计模式(iOS常用设计模式) Cocoa Design Patterns

BEESEXY“CoCoa·M可沐巧”(Cocoa melody) 系列上市

iOS:Cocoa编码规范 -[译]Coding Guidelines for Cocoa

合理的 Cocoa 和 Cocoa Touch 默认值

在 Cocoa/Cocoa Touch 中监控目录