[NSBundle mainBundle] 声明的 CFString 对象

Posted

技术标签:

【中文标题】[NSBundle mainBundle] 声明的 CFString 对象【英文标题】:CFString objects being declared by [NSBundle mainBundle] 【发布时间】:2012-01-25 13:52:53 【问题描述】:

我正在改进我的 ios cocos2d 游戏的性能。当我注意到一件事时,我正在借助 Instruments 工具检查应用程序的内存分配。 [NSBundle mainBundle] 调用声明和持有的 CFString 对象过多。它说,

类别:CFString(不可变) 负责任的调用者:[NSBundle mainBundle]

我的代码中有很多地方我写了以下几行

[[NSBundle mainBundle] pathForResource:@"resource-name" ofType:@"png" isDirectory:imageDirectory];

这个 CFString 问题是因为上面的代码,因为我在 pathForResource 方法中给出了一个硬编码的字符串吗?或者这个问题的原因是什么?有人可以帮忙吗?这个 CFString 分配占用了我大约 2Mb 的代码,所以我很担心。

最好的问候

【问题讨论】:

【参考方案1】:

这些 CFString 是由于您的应用程序包中有大量资源。在我的测试中,我发现为捆绑包根目录下的每个文件分配了 1 个 CFString。大概这是某种路径名的缓存。

我目前正在开发一个包含 1,000 个资源的应用程序,这些不可变字符串占用了大约 300K。当我删除其中的大部分时,我最终得到了大约 20K,其中大约 100 个 CFStrings 用于捆绑中的约 80 个资源。

似乎减少这些的答案是将资源放在包内的子目录中。您可以在 Xcode 中使用“文件夹引用”来执行此操作。

例如,您的游戏可能有 1,000 个 PNG。将它们放在项目中名为“Assets”的文件夹中(在磁盘上)。将“Assets”目录拖到 Xcode 中,而不是创建一个组,而是创建一个文件夹引用。

【讨论】:

嗨,杰西,感谢您的回答。请解释这将如何减少 CFString 对象的数量? 捆绑包根目录中的每个路径似乎都有 1 个 CFString。减少根目录的文件数量会减少 CFString 的数量。 非常感谢杰西。我肯定会尝试,并会让你们知道。再次感谢。能否请您准确说明生成了什么路径以及为什么没有为子文件夹中的资源生成路径? 我不知道,这进入了 iOS 的内部【参考方案2】:

不,这不是 NSBundle 分配字符串的原因,不,你没有做错任何事情。 -[NSBundle mainBundle] 实际上分配 2MB 的字符串似乎极不可能,所以我建议您查看其他一些分配堆栈跟踪,看看您是否能找到真正的罪魁祸首。

【讨论】:

所以如果有 Category: CFString (immutable) 和 Responsible Caller: [NSBundle mainBundle] 那么这到底是什么意思?因为这是我在 Instruments 中注意到的。 您是在(默认折叠)右侧边栏中查看完整的堆栈跟踪,还是只是在表格视图中查看 Instrument 的最佳猜测?

以上是关于[NSBundle mainBundle] 声明的 CFString 对象的主要内容,如果未能解决你的问题,请参考以下文章

NSBundle.mainBundle() 返回 nil

`NSBundle.mainBundle().URLForResource` 总是返回 `nil`

未找到 NSBundle mainBundle

NSBundle mainBundle 返回 nil

NSBundle mainBundle infoDictionary 返回 NULL

“[[NSBundle mainBundle] objectForInfoDictionaryKey:]” 有时返回 nil