从 iOS 包中加载 Nib 文件的更快方法?

Posted

技术标签:

【中文标题】从 iOS 包中加载 Nib 文件的更快方法?【英文标题】:Faster way to load Nib file from a bundle in iOS? 【发布时间】:2012-10-24 20:54:19 【问题描述】:

我有一个应用程序,它使用一组自定义“控件”,这些控件是使用类似于以下方法从 Xib 文件按需加载的:

NSArray * topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"AudioPlayer" owner:self options:nil];
InteractiveMovieView *newAudio = [topLevelObjects objectAtIndex:0];

这种方法效果很好,除非同时加载多个控件(在应用程序的一个“页面”上有效)。

每次从包中加载显然效率低下,但我找不到另一种方法来解决这个问题。我曾尝试将笔尖加载到 copy 属性中一次,并根据需要返回以供重复使用,但这不起作用,因为返回的副本绝不是空白笔尖的“干净”副本。

我希望这是有道理的,感谢所有帮助。

【问题讨论】:

【参考方案1】:

听起来您正在寻找UINib 类。来自文档:

只要您的应用程序需要重复实例化相同的 nib 数据,就应该使用 UINib 对象。例如,如果您的表格视图使用 nib 文件来实例化表格视图单元格,则将 nib 缓存在 UINib 对象中可以显着提高性能。

【讨论】:

你能解释一下为什么 [UINib nibWithNibName:bundle:] 可以提高性能吗?我认为它只是创建了一个指向 Nib 文件的 UINib 对象。繁重的工作在 [nib instantidateWithOwner:options:] 中,它确实取消了 nib 的归档(在我看来,这个操作要重得多) @entropy 您的陈述与文档相矛盾。 @nielsbot 是的,这肯定是矛盾的,但你不和我一样吗?人们说这很贵,那很贵,......没有理由:( 我认为 Apple 知道他们的代码是如何工作的,而且他们不会无缘无故地将其写在文档中。如果您有疑问,您应该对其进行分析。 UINib 缓存来自 nib 的 XML,因此不必每次都将其加载到内存中。虽然所有的取消归档都发生在 instantiateWithowner:options 期间,因此使用 UINib 不会看到巨大的性能优势,除非 nib 太大以至于加载 xml 需要大量时间。【参考方案2】:

按照 Rob 的建议,您可以执行以下操作:

@implmentation InteractiveMovieView (NibFactory)

+(id)movieView

    static UINib * __nib ;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^
        __nib = [ UINib nibWithNibName:@"AudioPlayer" bundle:nil ] ;
    );

    InteractiveMovieView * view = [ __nib instantiateWithOwner:nil options:nil ][0] ;
    return view ;


@end

【讨论】:

几乎所有繁重的工作都发生在通过instantiateWithOwner:options 取消归档视图的过程中。创建静态笔尖不会带来任何性能提升。 如果我理解@Rob 引用的文档,应该缓存UINib 对象,不是吗? 文档的措辞有些混乱。它表示UINib对象负责缓存,而不是你应该缓存UINib 查看instantiateWithOwner:options 的文档,了解繁重的工作发生在哪里:解压缩并实例化接收器的 nib 文件的内存内容,创建一个独特的对象树和一组***对象。 据我所知,通过仪器进行测试,使用 UINibloadNibNamed 在性能方面几乎没有区别。 据我所知确实 缓存了笔尖的数据——XML 本身。但是取消归档和实例化内存中的内容比加载 nib 的 xml 贵几个数量级。所以,是的,使用UINib 肯定会更好,但实际上它几乎没有什么区别,除非你有一个带有多个根对象的巨大 nib,它比典型的要大。

以上是关于从 iOS 包中加载 Nib 文件的更快方法?的主要内容,如果未能解决你的问题,请参考以下文章

出现“无法在捆绑包中加载 NIB”错误

无法在包中加载 NIB:'NSBundle 错误

iOS 10:致命异常:NSInternalInconsistencyException 无法在包中加载 NIB

无法在包中加载 NIB:NSBundle

MonoTouch <--> 静态库异常:无法在包中加载 NIB

无法在捆绑包中加载 NIB。可可豆项目