• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

ios - 在 for 循环中使用日期格式化程序的 dateFromString api 会产生巨大的内存问题

[复制链接]
菜鸟教程小白 发表于 2022-12-13 10:25:52 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我在 for 循环之外创建了一个 NSDateFormatter 的实例(或者可以说是一个实例变量),然后在 for 循环中将其用作 [dateFormatter dateFromString]。这给了我巨大的内存问题。我尝试使用 @autorelease 指令降低巨大的内存分配,其中我已将 for 循环移动到 autorelease block 。我还在自动释放 block 之外将 dateFormatter 实例设置为 nil 。由于 for 循环中的 dateFormatter,正在寻找一种更好的方法来降低内存消耗。

-(void)start {
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:10.0 target: self selectorselector(refresh) userInfo: nil repeats: YES];
}

-(void)refresh
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        // Code for Fetching data from server and parsing it
        CustomObject *obj = [Parser parseData:dictionary];
    });
}

@implementation Parser

+(CustomObject *)parseDataNSDictionary *) dictioanry {

    NSArray *array;
    array = [dictionary objectForKey"someKey"];

    NSDateFormatter *df = [[NSDateFormatter alloc] init];
    [df setDateFormat"yyyy-MM-dd'T'HH:mm:ss.SSSZ"];
    @autoreleasepool
    {
        for ( NSDictionary *dic in array)
        {
            NSDate *date = [df dateFromString:[dic objectForKey"key"]];
            nestedObj.startTime = date;
   // construct and store the custom Objects
   // add the nested objects to an array
            [obj.arr add:nestedObj];
            date = nil;
        }
    }
    df = nil;
    return obj;
}
@end



Best Answer-推荐答案


你的 @autoreleasepool 放错地方了。您需要在每个循环结束时排空池:

    for ( NSDictionary *dic in array)
    {
        @autoreleasepool {
            NSDate *date = [millisecondDateFormatter dateFromString:[dic objectForKey"key"]];
            obj.nestedObj.startTime = date;
            date = nil;
        }
    }

也就是说,我假设您的真实代码有很大不同。这段代码没有任何意义。您一遍又一遍地覆盖相同的 obj.nestedObj.startTime 。只有最后一个循环迭代才是重要的。但也许这是您创建示例时的转录错误。

请注意,没有理由像这样到处使用 x = nil。这会自动发生,您通常应该允许它这样做。


编辑:

只是在评论中触及@trojanfoe 的问题(这里没有什么重要的,这只是一个有趣的问题)。我们可以稍微探索一下 Foundation,看看它在做什么。几经周折之后,对 dateFromString: 的调用最终以一个名为 _getObjectValue: 的方法结束,最终在 OS X 版本中执行如下操作:

...
NSDate *date = (NSDate *)CFDateFormatterCreateDateFromString(NULL, (CFTypeRef)self, ...);
if (date != nil) { CFMakeCollectable((CFTypeRef)date); }
[date autorelease];
...

考虑到 getObjectValue:forString:range:error: 是最通用的形式,并且它是唯一的 dateFromString 引用,我们可以在不深入汇编的情况下直觉这一点,所以一切都可能成为瓶颈(这实际上是真的)。这种方法的 Swift 解释可以让您了解它可能会在某处自动释放:

func getObjectValue(_ obj: AutoreleasingUnsafePointer<AnyObject?>, forString string: String!, range rangep: UnsafePointer<NSRange>, error error: NSErrorPointer) -> Bool

当然,在实践中,您几乎从来没有认真考虑过这个问题 您应该假设您调用的任何 Cocoa 方法都可能生成自动释放的对象,并相应地执行。即使您可以证明它在特定版本的 Cocoa 中没有,Apple 也可以在未来的版本中自由更改,因此您应该始终期待它们。

关于ios - 在 for 循环中使用日期格式化程序的 dateFromString api 会产生巨大的内存问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28957796/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap