Cocoa - loadNibNamed:owner:topLevelObjects:from loaded bundle [英] Cocoa - loadNibNamed:owner:topLevelObjects: from loaded bundle

查看:820
本文介绍了Cocoa - loadNibNamed:owner:topLevelObjects:from loaded bundle的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在基于文档的Cocoa应用程序中,我使用以下实例化外部软件包中的多个对象(插件):

   - (NSMutableArray *)getPluginsOfType:(Class)type; 
{
NSBundle * main = [NSBundle mainBundle];
NSArray * allPlugins = [main pathsForResourcesOfType:@bundleinDirectory:@../ PlugIns];

NSMutableArray * availablePlugins = [NSMutableArray array];

(所有插件中的NSString *路径)
{
NSBundle * pluginBundle = [NSBundle bundleWithPath:path];
[pluginBundle load];
Class principalClass = [pluginBundle principalClass];
[availablePlugins addObject:principalClass];
}
return availablePlugins;
}

在其中的每一个中,一个nib文件加载到init,根视图与我的插件类中的属性。下面是一个最小的Plugin类定义:

  @interface插件

@property thePluginView;

@end

@implementation插件

- (instancetype)init
{
self = [super init];
if(self)
{
[NSBundle loadNibNamed:@NibNameowner:self];
}
return self;
}

@end

想要替换上面的调用NSBundle(因为它已被弃用为OS X 10.8+),并替换为:

  [[ NSBundle mainBundle] loadNIBNamed:@NibNameowner:self topLevelObjects:nil];但是,在这种情况下使用mainBundle自然不能在我的Plugin类中设置顶级对象引用,我怀疑因为mainBundle与插件的捆绑无关。 



我将如何实现呢?是否有一种方法可以找到当前包(也就是Plugin类来自的包)。



谢谢。

解决方案

我不清楚你究竟要问什么 - 加载类不在你的应用程序的捆绑包来自哪里,



也许以下会有帮助:



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



'你使用通过 [NSBundle mainBundle] 获得,因此从应用程序主包中加载nib。



没有当前束概念,但您可以获取表示其他束的 NSBundle 实例,例如与 NSBundle 的类方法 bundleWithURL 。因此,要从不同的bundle加载一个nib,首先创建一个引用该bundle的 NSURL ,然后创建一个 NSBundle



HTH



附录 - 问题更新后



+ loadNibName:owner:方法的描述 owner


如果此对象的类具有关联的bundle,则搜索该bundle以查找指定的nib文件;


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



所以在你的 Plugin 类中,你应该能够找到从 [NSBundle bundleForClass:[self class]] 加载它,然后调用 -loadNibNamed:owner:topLevelObjects:


In a document based Cocoa app, I am instantiating several objects (plugins) from external bundles using:

- (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;
}

Within each of those, a nib file is loaded upon init, which binds the root view with a property in my plugin class. Below a minimal Plugin class definition:

@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

While this works fine, I want to replace the above call to NSBundle (because it's deprecated for OS X 10.8+), and replace it with:

[[NSBundle mainBundle] loadNibNamed:@"NibName" owner:self topLevelObjects:nil];

However, using mainBundle in this case naturally fails to set the top level object reference in my Plugin class, I suspect cause mainBundle has nothing to do with the Plugin's bundle.

How would I go about achieving that? Is there a way to find the "current" bundle perhaps (the bundle that the Plugin class came from, so to say)?

Thanks.

解决方案

It is not clear to me exactly what you're asking - where is the "loading class" that is not in your application's bundle coming from, and what exactly do you mean by "loading class"?

Maybe the following will help:

loadNibNamed:owner:topLevelObjects: is an instance method and loads from the bundle the instance represents.

In your sample the instance you've used you obtain via [NSBundle mainBundle], so the nib is loaded from the applications main bundle.

There is no "current bundle" concept, but you can obtain an NSBundle instance representing other bundles, e.g. with NSBundle's class method bundleWithURL. So to load a nib from a different bundle first create an NSURL that references the bundle, then create an NSBundle based on that, and finally load the nib.

HTH

Addendum - After Question Updated

From the deprecated +loadNibName:owner: method's description of owner:

If the class of this object has an associated bundle, that bundle is searched for the specified nib file; otherwise, this method looks in the main bundle.

This is what you need to replicate when using -loadNibNamed:owner:topLevelObjects:. The method you need is NSBundle's bundleForClass: which returns the NSBundle object that dynamically loaded a class.

So in your Plugin class you should be able to find the bundle it was loaded from with [NSBundle bundleForClass:[self class]] and then call -loadNibNamed:owner:topLevelObjects: on that.

这篇关于Cocoa - loadNibNamed:owner:topLevelObjects:from loaded bundle的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆