Object-C中的排序和Compare陷阱
来源:http://m.blog.csdn.net/blog/u011883764/38868097
Date : 2015-12-24
一.Compare陷阱
NSString有多个compare相关方法:
- (NSComparisonResult)compare:(NSString *)string;
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask;
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange;
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange locale:(id)locale;
NSComparisonResult 是定义的一个枚举,定义如下:
typedef NS_ENUM(NSInteger, NSComparisonResult) {
NSOrderedAscending = -1L, NSOrderedSame, NSOrderedDescending
};
其中,NSOrderedSame 表示比较的两个字符串完全一致, 同时,在这个枚举中,它的值是 0.
字符串比较在程序中很常见,比如:
if ([str1 compare:@"some text"] == NSOrderedSame) {
// TODO
}
else {
// TODO
}
但是,如果如上中的str1为nil,根据Objective-C的消息调用规则(方法调用),对nil发送的任何消息,得到的返回都是nil。这样的情况下,运行时是不会像C/C++那样,出现空指针的非法访问而使得程序强行终止。也就是说,在Objective-C下面,即便str1为nil,也不会造成程序崩溃,而是会继续运行。
那么当str1为空的时候,[str1 compare:@"some text"] 消息的返回就会为nil。nil表示一个空的Objective-C对象,实际就是表示一个空指针,而它代表的值就是0,与NSOrderedSame的值相等. 如此,回到最前面的if语句,如果str1为nil,那么整个语句的值为真。这会给程序造成非常严重的问题,小则逻辑错误,UI显示错误等,大则会造成数据泄漏等等。。。所以,一旦出现这种情况,还是很严重的。
笔者个人建议,以上代码至少应该写为:
if (str1!=nil && [str1 compare:@"some text"] == NSOrderedSame) {
// TODO } else {
// TODO
}
二.排序
数字排序
//数字排序 - (void)sortNumber{ NSArray *originalArray = @[@"",@"",@"",@"",@"-1"]; //block比较方法,数组中可以是NSInteger,CGFloat等(需要转换) NSComparator finderSort = ^(id string1,id string2){ if ([string1 integerValue] > [string2 integerValue]) { return (NSComparisonResult)NSOrderedDescending; }else if ([string1 integerValue] < [string2 integerValue]){ return (NSComparisonResult)NSOrderedAscending; } else return (NSComparisonResult)NSOrderedSame; }; NSArray *resultArray = [originalArray sortedArrayUsingComparator:finderSort]; NSLog(@"排序结果:%@",resultArray); }
字符串排序
//字符串排序 - (void)sortString{ // 2. 非数字型字符串(注意用compare比较要剔除空数据(nil)) NSArray *charArray =@[@"string 1",@"String 21",@"string 12",@"String 11",@"String 02"]; NSStringCompareOptions comparisonOptions =NSCaseInsensitiveSearch|NSNumericSearch| NSWidthInsensitiveSearch|NSForcedOrderingSearch; NSComparator sort = ^(NSString *obj1,NSString *obj2){ NSRange range = NSMakeRange(,obj1.length); return [obj1 compare:obj2 options:comparisonOptions range:range]; }; NSArray *resultArray2 = [charArray sortedArrayUsingComparator:sort]; NSLog(@"字符串排序%@",resultArray2); }
字典排序
//字典排序 - (void)sortDicrionary{ NSMutableArray *array = [NSMutableArrayarrayWithObjects: @{@"obj0":@""}, @{@"obj3":@""}, @{@"obj1":@""}, @{@"obj2":@""}, @{@"obj4":@""}, nil]; NSArray *resultArray = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1,id obj2) { NSNumber *number1 = [[obj1 allKeys] objectAtIndex:]; NSNumber *number2 = [[obj2 allKeys] objectAtIndex:]; NSComparisonResult result = [number1 compare:number2]; //return result == NSOrderedAscending; //降序 return result == NSOrderedDescending;//升序 }]; NSLog(@"OrderedDescending:%@", resultArray); }
自定义对象排序
//自定义对象排序 - (void)sortCustomObject{ SLPerson *person1 = [[SLPerson alloc] init]; [person1 setName:@"ABCD"]; [person1 setAge:]; SLPerson *person2 = [[SLPersonalloc]init]; [person2 setName:@"ACBD"]; [person2 setAge:]; SLPerson *person3 = [[SLPerson alloc] init]; [person3 setName:@"ABDC"]; [person3 setAge:]; SLPerson *person4 = [[SLPerson alloc] init]; [person4 setName:@"ACDB"]; [person4 setAge:]; NSMutableArray *array = [NSMutableArray arrayWithObjects:person1, person3, person4, person2, nil]; NSSortDescriptor *sortDescriptor1 = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES]; //先按照age排序, NSSortDescriptor *sortDescriptor2 = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]; //如果age相同,按照name排序,以此类推 NSArray *tempArray = [array sortedArrayUsingDescriptors:[NSArray arrayWithObjects:sortDescriptor1, sortDescriptor2, nil]]; for(NSInteger i =; i < [tempArray count]; i++){ NSLog(@"%@--------%d\n", [[tempArray objectAtIndex:i] name], [[tempArray objectAtIndex:i] age]); }
}
代码链接:http://download.csdn.net/detail/u011883764/7827311
Object-C中的排序和Compare陷阱的更多相关文章
- Objective—C中的排序及Compare陷阱
campare陷阱 NSString有多个compare相关方法: - (NSComparisonResult)compare:(NSString *)string; - (NSComparisonR ...
- Hadoop学习笔记—11.MapReduce中的排序和分组
一.写在之前的 1.1 回顾Map阶段四大步骤 首先,我们回顾一下在MapReduce中,排序和分组在哪里被执行: 从上图中可以清楚地看出,在Step1.4也就是第四步中,需要对不同分区中的数据进行排 ...
- Java集合中对象排序
集合中的对象排序需求还是比較常见的.当然我们能够重写equals方法,循环比較:同一时候Java为我们提供了更易使用的APIs.当须要排序的集合或数组不是单纯的数字型时,通常能够使用Comparato ...
- Comparable与Comparator,java中的排序与比较
1:比较和排序的概念 比较:两个实体类之间按>,=,<进行比较. 排序:在集合类中,对集合类中的实体进行排序.排序基于的算法基于实体类提供的比较函数. 基本型别都提供了默认的比较算法,如s ...
- C# winform中listview排序
本文解决方案是采用下面链接中的解决方案.十分感谢这篇文章的作者bright:http://blog.163.com/shensc@126/blog/static/1312896522010614103 ...
- linux内核中的排序接口--sort函数
linux内核中的sort函数,其实跟我们所说的qsort函数很像,我们来看看qsort: qsort 的函数原型是 void qsort(void*base,size_t num,size_t wi ...
- .Net中集合排序的一种高级玩法
背景: 学生有名称.学号, 班级有班级名称.班级序号 学校有学校名称.学校编号(序号) 需求 现在需要对学生进行排序 第一排序逻辑 按学校编号(序号)排列 再按班级序号排列 再按学生学号排列 当然,在 ...
- STL中的排序算法
本文转自:STL中的排序算法 1. 所有STL sort算法函数的名字列表: 函数名 功能描述 sort 对给定区间所有元素进行排序 stable_sort 对给定区间所有元素进行稳定排序 ...
- C++中的排序
下面网站解释比较好 http://www.cnblogs.com/heyonggang/archive/2013/11/03/3404371.html 1. qsort(C中的函数加上stdlib.h ...
随机推荐
- Delphi中使用@取函数地址的问题(转)
Delphi中使用@取函数地址的问题 例如以下代码:unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes ...
- 使用 TFDConnection 的 pooled 连接池
从开始看到这个属性,就一直认为他可以提供一个连接池管理功能, 苦于文档资料太少, 甚至在帮助中对该属性的使用都没有任何介绍,如果你搜索百度,也会发现基本没资料. 最后终于在其官方网站看到了其完整相关的 ...
- iOS原生JSON解析.
- (IBAction)accessInterfaceBtnPressed:(id)sender { NSError *error; NSString *URL=@"ht ...
- umask:遮罩码
查看umask:umask 创建文件:-umask 文件默认不能具有执行权限 创建目录:-umask 设置umask:umask 0022 生效访范围:当前shell
- Centos6.5和Centos7 php环境搭建如何实现呢
首先我们先查看下centos的版本信息 代码如下: #适用于所有的linux lsb_release -a#或者cat /etc/redhat-release#又或者rpm -q centos-rel ...
- java利用zxing编码解码一维码与二维码
最近琢磨了一下二维码.一维码的编码.解码方法,感觉google的zxing用起来还是比较方便. 本人原创,欢迎转载,转载请标注原文地址:http://wallimn.iteye.com/blog/20 ...
- 探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法
前言相信这样一个问题,大家都不会陌生,“有什么的方法可以使Android的程序APK不用安装,而能够直接启动”.发现最后的结局都是不能实现这个美好的愿望,而腾讯Android手机游戏平台却又能实现这个 ...
- Unix/Linux编程实践教程(一:进程、管道)
execvp在程序中启动新程序: 用fork创建新进程: forkdemo2代码: 测试fork的时候参考<Linux权威指南>阅读笔记(3) 使用了patch: [root@local ...
- ASP.NET数据验证控件的常用的属性
一.非空验证 RequiredFieldValidator ControlToValidate 所验证的控件ID Text 出错时的提示的文本 ErrorMessage 提交给Validati ...
- 对js原型的理解
1.值类型和引用类型,引用类型都是对象,通过typeof()测试类型,instanceof测试是否是对象.对象是属性的集合. 2.对象都是由函数创建的,函数又是一个对象. 3.函数有一个默认的属性,叫 ...