为什么要优化NSDateFormatter?

首先,过度的创建NSDateFormatter用于NSDateNSString之间转换,会导致App卡顿,打开Profile工具查一下性能,你会发现这种操作占CPU比例是非常高的。据官方说法,创建NSDateFormatter代价是比较高的,如果你使用的非常频繁,那么建议你缓存起来,缓存NSDateFormatter一定能提高效率。

Creating a date formatter is not a cheap operation. If you are likely to use a formatter frequently, it is typically more efficient to cache a single instance than to create and dispose of multiple instances. One approach is to use a static variable

优化方式有哪些?

a.延迟转换

即只有在UI需要使用转换结果时在进行转换。

b.Cache in Memory

根据NSDateFormatter线程安全性,不同的iOS系统版本内存缓存如下:

  • prior to iOS 7

如果直接采用静态变量进行存储,那么可能就会存在线程安全问题,在iOS 7之前,NSDateFormatter是非线程安全的,因此可能就会有两条或以上的线程同时访问同一个日期格式化对象,从而导致App崩溃。


+ (NSDateFormatter *)cachedDateFormatter { NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary]; NSDateFormatter *dateFormatter = [threadDictionary objectForKey:@"cachedDateFormatter"]; if (!dateFormatter) { dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setLocale:[NSLocale currentLocale]]; [dateFormatter setDateFormat: @"YYYY-MM-dd HH:mm:ss"]; [threadDictionary setObject:dateFormatter forKey:@"cachedDateFormatter"]; } return dateFormatter; }
  • iOS 7 or later

在iOS 7、macOS 10.9及以上系统版本,NSDateFormatter都是线程安全的,因此我们无需担心日期格式化对象在使用过程中被另外一条线程给修改,为了提高性能,我们还可以在上述代码块中进行简化(除去冗余部分)。


static NSDateFormatter *cachedDateFormatter = nil; + (NSDateFormatter *)cachedDateFormatter { NSMutableDictionary // If the date formatters aren't already set up, create them and cache them for reuse. if (!dateFormatter) { dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setLocale:[NSLocale currentLocale]]; [dateFormatter setDateFormat: @"YYYY-MM-dd HH:mm:ss"]; } return dateFormatter; }

如果缓存了日期格式化或者是其他依赖于current locale的对象,那么我们应该监听NSCurrentLocaleDidChangeNotification通知,当current locale变化时及时更新被缓存的日期格式化对象。

In theory you could use an auto-updating locale (autoupdatingCurrentLocale) to create a locale that automatically accounts for changes in the user’s locale settings. In practice this currently does not work with date formatters.

Apple Threading Programming Guide

c.利用标准C语言库

如果时间日期格式是固定的,我们可以采用C语言中的strptime函数,这样更加简单高效。


- (NSDate *) easyDateFormatter{ time_t t; struct tm tm; char *iso8601 = "2016-09-18"; strptime(iso8601, "%Y-%m-%d", &tm); tm.tm_isdst = -1; tm.tm_hour = 0;//当tm结构体中的tm.tm_hour为负数,会导致mktime(&tm)计算错误 /** //NSString *iso8601String = @"2016-09-18T17:30:08+08:00"; //%Y-%m-%d [iso8601String cStringUsingEncoding:NSUTF8StringEncoding] { tm_sec = 0 tm_min = 0 tm_hour = 0 tm_mday = 18 tm_mon = 9 tm_year = 116 tm_wday = 2 tm_yday = 291 tm_isdst = 0 tm_gmtoff = 28800 tm_zone = 0x00007fd9b600c31c "CST" } ISO8601时间格式:2004-05-03T17:30:08+08:00 参考Wikipedia */ t = mktime(&tm); //http://pubs.opengroup.org/onlinepubs/9699919799/functions/mktime.html //secondsFromGMT: The current difference in seconds between the receiver and Greenwich Mean Time. return [NSDate dateWithTimeIntervalSince1970:t + [[NSTimeZone localTimeZone] secondsFromGMT]]; }

相关资料:

Date Formate Patterns :

Standard C library

ISO_8601

性能优化之NSDateFormatter的更多相关文章

  1. (转)Foundation-性能优化之NSDateFormatter

    性能优化之NSDateFormatter 为什么要优化NSDateFormatter? 首先,过度的创建NSDateFormatter用于NSDate与NSString之间转换,会导致App卡顿,打开 ...

  2. 【腾讯Bugly干货分享】微信读书iOS性能优化

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/578c93ca9644bd524bfcabe8 “8小时内拼工作,8小时外拼成长 ...

  3. <转>iOS性能优化:Instruments使用实战

    最近采用Instruments 来分析整个应用程序的性能.发现很多有意思的点,以及性能优化和一些分析性能消耗的技巧,小结如下. Instruments使用技巧 关于Instruments官方有一个很有 ...

  4. iOS性能优化:Instruments使用实战

    iOS性能优化:Instruments使用实战   最近采用Instruments 来分析整个应用程序的性能.发现很多有意思的点,以及性能优化和一些分析性能消耗的技巧,小结如下. Instrument ...

  5. 微信读书 iOS 性能优化总结

    微信读书作为一款阅读类的新产品,目前还处于快速迭代,不断尝试的过程中,性能问题也在业务的不断累积中逐渐体现出来.最近的 1.3.0 版本发布后,关于性能问题的用户反馈逐渐增多,为此,团队开始做一些针对 ...

  6. iOS程序性能优化

    iOS程序性能优化 一.初级 使用ARC进行内存管理 在iOS5发布的ARC,它解决了最常见的内存泄露问题.但是值得注意的是,ARC并不能避免所有的内存泄露.使用ARC之后,工程中可能还会有内存泄露, ...

  7. iOS性能优化

    最近采用Instruments 来分析整个应用程序的性能.发现很多有意思的点,以及性能优化和一些分析性能消耗的技巧,小结如下. Instruments使用技巧 关于Instruments官方有一个很有 ...

  8. IOS 性能优化的建议和技巧

    IOS 性能优化的建议和技巧 本文来自iOS Tutorial Team 的 Marcelo Fabri,他是Movile的一名 iOS 程序员.这是他的个人网站:http://www.marcelo ...

  9. UITableView性能优化及手工绘制UITableViewCell

    提高表视图的性能 UITableView作为应用中最常用的视图,它的性能优化问题几乎是经常提及.下面对在非网络访问情况下的表视图性能优化进行了主要的几点说明: 1.自定义类或XIB文件时 在系统提供的 ...

随机推荐

  1. PHP博客小项目之知识点(1)

    一.博客系统介绍 Blog.Bloger.web log(网络日志) 博客主要发布一些文章.图片:博客一般都是个人博客: 博客的文章,一般都是按照时间倒序排列: 博客,仅音译,英文名为Blogger, ...

  2. ASP.NET-FineUI开发实践-4(二)

    在网上找了找,实验了一下window弹出和关闭的动画效果分享一下. 接上次的代码 default.js window_tips.animCollapse= true;//打开动画效果 window_t ...

  3. java -jar start.jar和nohup java -jar xxx.jar > test.log &的区别

    nohup用在什么地方? KD3EE49RD38

  4. CSS实现垂直居中的常用方法

    在前端开发过程中,盒子居中是常常用到的.其中 ,居中又可以分为水平居中和垂直居中.水平居中是比较容易的,直接设置元素的margin: 0 auto就可以实现.但是垂直居中相对来说是比较复杂一些的.下面 ...

  5. 创建实体数据模型需要注意的,不要选单复数形式,否则AddObject出问题

    //这个测试太不容易了,总是出错,addInfo 方法进去,最后调用context对象.AddObject(),也就是context.AddObject(entitySetName, entity); ...

  6. (转)asp.net中Literal与label的区别

    asp.net中Literal与label的区别 一.Literal Web 服务器控件概述(摘于MSDN) 可以使用 Literal Web 服务器控件作为页面上其他内容的容器.Literal 最常 ...

  7. linux定时执行任务 转

    转自:http://www.cnblogs.com/thinksasa/archive/2013/06/06/3121030.html linux定时执行任务   (1)Linux下如何定时执行php ...

  8. 武汉科技大学ACM:1001: 华科版C语言程序设计教程(第二版)习题6.7

    Problem Description 输出杨辉三角前n行. Input 输入一个数n(n <= 9) Output 输出杨辉三角前n行.(注意行末不能有多余的空格,数字以%3d的格式输出) S ...

  9. C++朝花夕拾【更新】

    C++拾遗 更新一些平时遇到的小细节: 1.关于类的无参构造函数和带有全部默认参考值的构造函数的区别 书上说的是带有全部默认值的构造函数就是无参构造函数,私以为不以为然,来看下边这个例子: #incl ...

  10. web前端知识

    4.表格与表单 4.1 动态添加行 <script language=”javascript”> window.onload=function(){ var oTr = document. ...