为什么要优化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. ssh key报but this does not map back to the address – POSSIBLE BREAK-IN ATTEMPT!错误

    在/etc/hosts 文件加上对方的主机名  ip地址,可以ping通主机名即可.

  2. 32位和64位adb下载及安装

    一.已安装android sdk时 1.拷贝 从%ANDROID_HOME/platform-tools 下拷贝如下文件到/System32和/SysWOW64下即可. adb.exe AdbWinA ...

  3. WebSQL实例记录

    <table id="content"> </table> <br> <input type="button" id= ...

  4. Js正则表达式提取图片地址

    JavaScript使用正则表达式和Replace两种方法提取IMG标签图片地址,代码如下: /正则表达式 <script language="javascript"> ...

  5. C#实现打印与打印预览功能(转)

    在windows应用程序中文档的打印是一项非常重要的功能,在以前一直是一个非常复杂的工作,Microsoft .Net Framework的打印功能都以组件的方式提供,为程序员提供了很大的方便,但是这 ...

  6. 用Set中元素做条件查询

    一个老师教许多学生,一个学生被许多老师教,一个学生有好多书,同一种书被许多同学拥有.查询教拥有书"a"的学生的老师:   class teacher{   String id;   ...

  7. 如何解析复杂的C语言声明

    C语言中有时会出现复杂的声明,比如   char * const * (*next) (); //这是个什么东东?   在讲复杂声明的分析方法前,先来个补充点.   C语言变量的声明始终贯彻两点 :  ...

  8. 隐藏NGINX服务器名称 和版本号

    隐藏NGINX服务器名称: 修改或隐藏服务器名称需要修改源码nginx.h,nginx.h在src/core/目录下 .具体操作如下: 把下面两个宏的值修改为自己设定的值,例如"NGX&qu ...

  9. Unity3D 经验记录

    1.using UnityEngine.SceneManagement; 当在01场景调用02场景时,再载入回01场景时,代码保存的变量不会初始化,预制物体脚本内的变量会初始化. 2.当子物体太多时, ...

  10. Android 自定义控件 EditText输入框两边加减按钮Button

    自己封装的一个控件:EditText两边放加减按钮Button来控制输入框的数值 Demo 下载地址: 第一版:http://download.csdn.net/detail/zjjne/674086 ...