来源: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陷阱的更多相关文章

  1. Objective—C中的排序及Compare陷阱

    campare陷阱 NSString有多个compare相关方法: - (NSComparisonResult)compare:(NSString *)string; - (NSComparisonR ...

  2. Hadoop学习笔记—11.MapReduce中的排序和分组

    一.写在之前的 1.1 回顾Map阶段四大步骤 首先,我们回顾一下在MapReduce中,排序和分组在哪里被执行: 从上图中可以清楚地看出,在Step1.4也就是第四步中,需要对不同分区中的数据进行排 ...

  3. Java集合中对象排序

    集合中的对象排序需求还是比較常见的.当然我们能够重写equals方法,循环比較:同一时候Java为我们提供了更易使用的APIs.当须要排序的集合或数组不是单纯的数字型时,通常能够使用Comparato ...

  4. Comparable与Comparator,java中的排序与比较

    1:比较和排序的概念 比较:两个实体类之间按>,=,<进行比较. 排序:在集合类中,对集合类中的实体进行排序.排序基于的算法基于实体类提供的比较函数. 基本型别都提供了默认的比较算法,如s ...

  5. C# winform中listview排序

    本文解决方案是采用下面链接中的解决方案.十分感谢这篇文章的作者bright:http://blog.163.com/shensc@126/blog/static/1312896522010614103 ...

  6. linux内核中的排序接口--sort函数

    linux内核中的sort函数,其实跟我们所说的qsort函数很像,我们来看看qsort: qsort 的函数原型是 void qsort(void*base,size_t num,size_t wi ...

  7. .Net中集合排序的一种高级玩法

    背景: 学生有名称.学号, 班级有班级名称.班级序号 学校有学校名称.学校编号(序号) 需求 现在需要对学生进行排序 第一排序逻辑 按学校编号(序号)排列 再按班级序号排列 再按学生学号排列 当然,在 ...

  8. STL中的排序算法

    本文转自:STL中的排序算法 1. 所有STL sort算法函数的名字列表: 函数名    功能描述 sort   对给定区间所有元素进行排序 stable_sort 对给定区间所有元素进行稳定排序 ...

  9. C++中的排序

    下面网站解释比较好 http://www.cnblogs.com/heyonggang/archive/2013/11/03/3404371.html 1. qsort(C中的函数加上stdlib.h ...

随机推荐

  1. oracle 序列 ,check约束

    ====================序列 //查询当前用户序列 select * from user_sequences //查询所有序列 select * from all_sequences; ...

  2. Linux设备模型(9)_device resource management ---devm申请空间【转】

    转自:http://www.wowotech.net/linux_kenrel/device_resource_management.html . 前言 蜗蜗建议,每一个Linux驱动工程师,都能瞄一 ...

  3. JVM 指令集

    指令码 助记符 说明 0x00 nop 什么都不做 0x01 aconst_null 将null推送至栈顶 0x02 iconst_m1 将int型-1推送至栈顶 0x03 iconst_0 将int ...

  4. Lucas定理模板

    用于大组合数对p取模的计算. #include <cstdio> #include <iostream> #include <cmath> #include < ...

  5. SQLServer学习笔记<>日期和时间数据的处理(cast转化格式、日期截取、日期的加减)和 case表达式

    日期和时间数据的处理. (1)字符串日期 ‘20080301’,这一串为字符串日期,但必须保证为四位的年份,两位的月份,两位的日期.例如,查询订单表日期大于‘20080301’.可以这样写: 1 se ...

  6. set_include_path — 设置 include_path 配置选项为当前脚本设置 include_path 运行时的配置选项。

    说明 string set_include_path ( string $new_include_path ) 为当前脚本设置 include_path 运行时的配置选项. 参数 new_includ ...

  7. js 对象toString()方法

    ({}+{}).length == 30; ({}).toString() '[object Object]' 当对象需要调用toString()方法时会被自动调用.

  8. 【转】启动 Eclipse 弹出“Failed to load the JNI shared library jvm.dll”错误的解决方法! .

    转载地址:http://blog.csdn.net/zyz511919766/article/details/7442633 原因1:给定目录下jvm.dll不存在. 对策:(1)重新安装jre或者j ...

  9. hbase regionserver IO问题

    regionserver日志: java.io.IOException: Connection reset by peer         at sun.nio.ch.FileDispatcherIm ...

  10. JQuery知识快览之二—事件

    事件是脚本语言的核心.本文将为大家介绍JQuery支持的一些事件和如何自定义事件 JQuery内置事件 1.Document加载事件 JQuery提供了ready,load,unload三个Docum ...