开发中,我们有时需要对中文进行一些处理,如获取字符串中的所有中文字符等。对于中文的处理,首要是进行中文范围的确定。由于中文是以Unicode的形式进行编码存储,我们可通过对中文Unicode编码区域的确定,进而确定中文的范围。这方面,已经有很多统一标准(如CJK Unified Ideographs等),我们只需进行一些综合整理即可:1
2
3
4
5
6
7
8
9CJK统一汉字 4E00-9FFF
扩展A区用字 3400-4DBF
扩展B区用字 20000-2A6DF
扩展C区用字 2A700-2B73F
扩展D区用字 2B740-2B81F
扩展E区用字 2B820-2CEAF
CJK兼容汉字 F900-FAFF
扩展B区兼容用字 2F800-2FA1F
NSDate 日期转换为对应的星座或生肖
最近遇到个需求,需将日期转换为与之对应的占星星座( Astrological Zodiac Sign)
及生肖(Chinese Zodiac Sign)。在讨论具体实现前,我们可以先对时间处理从概念到实现上进行一些了解和回顾。
首先,从概念上,我们知道时间是独立存在的,日期是时间在特定历法中的表现。当然,在实际生活中,日期还受地理时区等因素影响。从概念出发,我们可以理解,平时讨论的日期更多地是指特定历法和时区下的某个时间。比如北京时间9点,公历2016年9月1日,农历八月十五等。
而在Cocoa
框架中,苹果对时间和日期的处理方式是这样的:1
time -> NSTimeInterva -> NSDate -> NSCalendar/NSTimeZone/NSDateComponents/NSDateComponentFormatter/NSDateFormatter -> date
iOS 集合存取结构体变量
最近开发中遇到一个需求,需将结构体变量存入一个集合中,并从集合中取出。实现思路上,由于结构体是C类型的数据结构,我们应当先通过NSValue
对结构体变量进行装箱操作,之后将装箱后的NSValue
对象存入集合,最后再从集合内获取NSValue
对象并将其拆箱为结构体变量。以存取CGColorRef
变量为例,具体实现如下:
首先,对结构体变量进行装箱及拆箱的处理。查看系统UIGeometry.h
文件,我们可以发现对于一些结构体,系统已进行了装箱及拆箱的处理:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19@interface NSValue (NSValueUIGeometryExtensions)
+ (NSValue *)valueWithCGPoint:(CGPoint)point;
+ (NSValue *)valueWithCGVector:(CGVector)vector;
+ (NSValue *)valueWithCGSize:(CGSize)size;
+ (NSValue *)valueWithCGRect:(CGRect)rect;
+ (NSValue *)valueWithCGAffineTransform:(CGAffineTransform)transform;
+ (NSValue *)valueWithUIEdgeInsets:(UIEdgeInsets)insets;
+ (NSValue *)valueWithUIOffset:(UIOffset)insets NS_AVAILABLE_IOS(5_0);
- (CGPoint)CGPointValue;
- (CGVector)CGVectorValue;
- (CGSize)CGSizeValue;
- (CGRect)CGRectValue;
- (CGAffineTransform)CGAffineTransformValue;
- (UIEdgeInsets)UIEdgeInsetsValue;
- (UIOffset)UIOffsetValue NS_AVAILABLE_IOS(5_0);
@end
UIImage 二分压缩图片
开发中,通常需要对图片进行压缩处理(多用于图片压缩上传),一般我们可能会直接使用系统提供的API将图片对象转为Data对象以实现需求:1
2
3
4
5Returns the data for the specified image in PNG format.
UIKIT_EXTERN NSData * UIImagePNGRepresentation(UIImage *image);
Returns the data for the specified image in JPEG format.
UIKIT_EXTERN NSData * UIImageJPEGRepresentation(UIImage *image, CGFloat compressionQuality);
iOS 遍历可变集合并移除集合内指定类别元素
开发中我们会遇到这样一种需求,在遍历可变集合时,移除集合内指定类别的元素。比如,移除所有Null类别的元素等。一般而言思路有两种,一种是双集合模式,另一种是单集合模式。双集合模式也叫副本模式,具体思路为,区分原元素集合及移除元素集合,匹配移除。一般有两种实现方式,以数组为例:
第一种,遍历原元素数组,将移除元素加入移除元素数组,最后统一从原元素数组移除:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// 原元素集合
NSMutableArray *array = @[@"1", @"11", @"111", [NSNull null], @"1111"].mutableCopy;
// 移除元素集合
NSMutableArray *removedArray = [NSMutableArray array];
for (id element in array)
{
if ([element isKindOfClass:[NSString class]])
{
[removedArray addObject:element];
}
}
[array removeObjectsInArray:removedArray];
NSLog(@"%@", array);
UIImage 运行时替换imageNamed:方法
iOS开发中,图片长期占用内存空间往往会导致应用内存空间过大,进而引发系统看门狗杀死应用。因而,如何有效地管理应用图片占用内存空间,并在适当的时候将其释放,对于提升程序的稳定性有重要意义。而一个显而易见的做法是,对于一些空间较大或不常显示的图片,使用imageWithContentsOfFile:
方法替代imageNamed:
方法进行创建。
通常我们创建图片会选择使用imageNamed:
方法:1
2
3
4
5This method looks in the system caches for an image object with the specified name and returns the variant of that image that is best suited for the main screen. If a matching image object is not already in the cache, this method locates and loads the image data from disk or from an available asset catalog, and then returns the resulting object.
+ (UIImage *)imageNamed:(NSString *)name;
[UIImage imageNamed:@"test.jpg"];
iOS 处理首次登录和再次登录(游客登录)
很多应用都会有这样一种登录设置:初次登录显示初次登录界面,若用户不登录可选择游客身份进入应用,当点击应用显示界面的某部分时,则弹出再次登录页面提示用户登录,此时用户登录则以用户身份进入应用。明析业务需求后,便可根据业务需求进行业务设计,可以先通过逻辑图理顺业务:
AFNetworking3.0 网络请求工具类的简单封装
开发中,通常需要对网络请求进行一些封装处理以方便开发人员调用。当前,大多数iOS项目都采用Mattt Thompson主导的AFNetworking
开源库处理网络请求。有些项目里直接使用AFNetworking
的相关请求方法,把请求的实现直接暴露在外部。从程序设计的角度看,这是不合适的。请求实现分散在项目的各个角落,当需要同时修改请求的某个配置时,注定是场灾难。因而,我们一般会在AFNetworking
等网络库的基础上,进行一层抽象,通过网络请求工具类包装接口,统一调度,并依据项目自身接口环境配置请求参数。以下模拟接口环境,对AFNetworking 3.0
网络请求库进行一些简单的封装:
首先,创建网络请求工具类,并进行一些统一配置:1
2
3
4
5
6
7
8
9
10
11
12
13@property (nonatomic, strong) AFHTTPSessionManager *manager;
+ (CHHTTPHelper *)defaultHTTPHelper
{
static CHHTTPHelper *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
NSAttributedString 实现文字遮盖效果
最近接到一个需求,文本长度为2-3个文字,两个文字长度的文本要求中间存在空距,左右顶边,且整体文本长度与三个文字的文本长度保持一致。效果如下:
最简单的实现是让UI把文字做成图片直接使用。第二种则是文本内加空格:1
[NSString stringWithFormat:@"爱 好:"];
但是这种方法的问题在于由于文字font的存在,有时候,添加空格后文本的长度无法与三个文字的文本长度一致。这时候我们还可以选择第三种方案,保持文字长度一致,再遮盖部分文字,保留显示文字:1
2
3
4
5
6居住地:____ 职一业:____
爱一好:____ 电一话:____
职一业: -> 职 业:
爱一好: -> 爱 好:
电一话: -> 电 话:
NSDecimalNumber 四舍五入到指定位数
项目里经常有这么一种需求,把小数四舍五入到指定位数,查阅文档,我们发现系统提供了NSDecimalNumber
类方便我们实现需求。NSDecimalNumber
是系统提供的一个专门处理十进位制数的类:1
NSDecimalNumber, an immutable subclass of NSNumber, provides an object-oriented wrapper for doing base-10 arithmetic. An instance can represent any number that can be expressed as mantissa x 10^exponent where mantissa is a decimal integer up to 38 digits long, and exponent is an integer from –128 through 127.
NSDecimalNumber
提供了处理舍入问题的方法:1
2
3Rounds the receiver off in the way specified by behavior and returns the result, a newly createdNSDecimalNumber object.
- (NSDecimalNumber *)decimalNumberByRoundingAccordingToBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
该方法需要调用者提供一个遵循NSDecimalNumerBehaviors
协议的执行者来处理舍入问题。这里我们无需自定义一个类,只需使用系统提供的NSDecimalNumberHandler
类来处理。该类已遵循NSDecimalNumerBehaviors
协议,且提供了一些方法方便我们实现:1
NSDecimalNumberHandler is a class that adopts the NSDecimalNumberBehaviors protocol. This class allows you to set the way an NSDecimalNumber object rounds off and handles errors, without having to create a custom class.