【问题标题】:Objective C iPhone performance issueObjective C iPhone性能问题
【发布时间】:2010-04-26 09:06:34
【问题描述】:

好吧,伙计们,我正在开发一个 iPhone 应用程序,我有一个遵循单例设计模式的模型类。

现在我有一个 NSArray,它在 init 方法中初始化为大约 1000 个 NSString。

现在我需要在一些视图控制器中使用这些数据。所以我导入 Model.h,我在视图控制器中创建了一个 NSString 对象数组并将数据设置给它。但现在的问题是,我现在分配了 2000 个 NSString,由于内存考虑,我认为这在 iPhone 上并不是一件好事。

释放模型对象没有帮助,因为我已经根据模式重写了释放方法以释放任何内容,并且我现在无法更改设计,因为现在很多代码都在假设模型是单例的情况下工作。

& 未来可能最初的 NSStrings 可能会增长到 2000 甚至更多&然后我将一次分配 4000 个 NSStrings ....

我有点困惑如何去做任何建议

【问题讨论】:

  • 你的字符串对象在什么时候被复制?为什么不直接重复使用它们?

标签: iphone objective-c cocoa performance


【解决方案1】:

几千个字符串几乎不占用任何内存。 4000 个字符串需要几百 kB,具体取决于长度。 (这里的经验法则是字符串长度 + 20)。

编辑:实际上可能更像是字符串长度 + 30 或 40;我不确定 NSArray 增加了多少开销。

重新编辑:鉴于以下问题的信息;您可能最多可以加载几百个字符串;就在您正在浏览的区域附近;基本上将您的 SQLite 访问转换为一个稀疏数组,该数组在搜索区域周围缓存一些字符串。当然,我不认为这是必要的;如果字符串是位置名称,它们的平均字节大小可能为 20-30 字节; (非常)粗略估计 300k 的内存以将它们全部永久保存在内存中,从而大大减少访问时间并提供更好的用户体验。 iPhone 没有很多内存。但是您至少可以负担得起几兆字节; 300k 不会伤到你。

【讨论】:

    【解决方案2】:

    如果不了解更多关于您的实现,很难提供具体建议——您的字符串来自哪里?一般来说,这种情况下最好的性能优化是延迟加载。如果您有表格视图,以下是一些使用不同技术减少内存占用的方法示例:

    • 核心数据:通常不是问题,因为对象会发生故障并自动获取。
    • SQLite: 同样,这通常不是问题 - 每次需要特定值时(例如,当表格视图单元格需要显示字符串时)都需要查询数据库。
    • Internet:在表格视图单元格可见时启动请求(通常通过线程)。
    • XML:比较棘手,但使用基于 SAX(事件)的解析而不是 DOM 解析(将整个文档加载到内存)来查找值。

    话虽如此,如果您做出了难以逆转的设计决策,则可能无法在不进行重大重构的情况下显着减少内存占用。

    编辑:根据其他答案,可能不用担心,但是如果您要针对内存进行优化,则不会在应用程序启动时加载所有 SQLite 值,而是从cellForRowAtIndexPath 中的 SQLite。使用 Core Data 可以更轻松地解决这类问题——我强烈建议使用 Core Data 而不是直接使用 SQLite(尽管这听起来好像您在开发方面可能太过分了,无法在这一点上切换)。

    【讨论】:

    • 好的,我有类似城市勺子应用程序的东西。所有的字符串都加载到 UIPickerView,1000 最初它们都是从 Sqlite 加载的。现在这些字符串只是你可以说的位置。我还有其他与这些字符串相关的信息,例如赞许次数、用户评论等,我已经为此实现了 KVO [self addObserver:model forKeyPath:@"selectedRowIndex" options:NSKeyValueObservingOptionNew context:model];每当pickerview中的行更改时,都会从sqlite获取更新的信息并显示在picker下方。用户可以摇动或按下按钮来选择随机位置
    【解决方案3】:

    如果您的模型对象真的是单例,那么您需要做的就是从视图控制器中的模型对象中获取字符串并使用它们。我不明白为什么你会得到重复。

    使用 NSString,只要字符串是不可变的,复制方法应该只保留要复制的对象并将相同的对象返回给您。此外,如果您的字符串是常量字符串,即定义如下:

    NSString* foo = @"bar";
    

    它们实际上是可执行文件的一部分,在运行时不会占用额外的 RAM。

    【讨论】:

    • Jeremy 对象属于不同的类,你确定..?因为我相信来自不同类的对象在可可的任何条件下都不会共享任何数据。我在 Apples 文档中读到了类似的内容,我认为是这样......但我不确定
    • 但是他们共享的数据是包含指向对象的指针的C变量。如果您有一个保留 ivar,则使用该属性为其分配一个对象只会为您提供一个指向内存中同一对象的新指针。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-28
    • 2011-07-29
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    • 1970-01-01
    相关资源
    最近更新 更多