• NSNumber 、 NSValue 、 日期处理 、 集合类 、 NSArray(一)


    1 基本数据类型的封装

    1.1 问题

    我们所学的所有基本数据类型,如int、float、double、char等,都不是对象,不能向它们发送消息。然而,在Foundation中的许多类,如NSArray,都要求使用对象作为其值,因此不能将任何基本数据类型直接存储到这些类的对象当中。要存储任何基本数据类型,都必须将这些数据封装成对象。

    1.2 步骤

    实现此案例需要按照如下步骤进行。

    步骤一:封装整型数据

    代码如下所示:

     
    1. #import <Foundation/Foundation.h>
    2. int main(int argc, const char * argv[])
    3. {
    4. @autoreleasepool {
    5. // insert code here...
    6. int i = 10;
    7. //装箱
    8. NSNumber* intNum = [NSNumber numberWithInt:i];
    9. //拆箱
    10. int i2 = [intNum intValue];
    11. NSLog(@"%d", i2);
    12. }
    13. return 0;
    14. }

    在上述代码中,以下代码:

     
    1. int i = 10;
    2. //装箱
    3. NSNumber* intNum = [NSNumber numberWithInt:i];

    将整型变量i封装成NSNumber类的对象,这一过程称为装箱。封装的过程是使用NSNumber类的方法numberWithInt,该方法带有一个实参,是要封装的整型变量。返回值是封装好的NSNumber类的对象。

    在上述代码中,以下代码:

     
    1. //拆箱
    2. int i2 = [intNum intValue];
    3. NSLog(@"%d", i2);

    是将封装了整型数据的NSNumber类对象还原成整型变量值,这一过程成为拆箱。使用NSNumber类的intValue方法,将NSNumber类对象中封装的整型数据还原。

    步骤二:封装字符型数据

    代码如下所示:

     
    1. #import <Foundation/Foundation.h>
    2. int main(int argc, const char * argv[])
    3. {
    4. @autoreleasepool {
    5. // insert code here...
    6. int i = 10;
    7. //装箱
    8. NSNumber* intNum = [NSNumber numberWithInt:i];
    9. //拆箱
    10. int i2 = [intNum intValue];
    11. NSLog(@"%d", i2);
    12. char c = 'a';
    13. //装箱
    14. NSNumber* charNum = [NSNumber numberWithChar:c];
    15. //拆箱
    16. char c2 = [charNum charValue];
    17. NSLog(@"%c", c2);
    18. }
    19. return 0;
    20. }

    在上述代码中,以下代码:

    1. char c = 'a';
    2. //装箱
    3. NSNumber* charNum = [NSNumber numberWithChar:c];

    将字符型变量c封装成NSNumber类的对象。封装的过程是使用NSNumber类的方法numberWithChar,该方法带有一个实参,是要封装的字符型变量。返回值是封装好的NSNumber类的对象。

    在上述代码中,以下代码:

    1. //拆箱
    2. char c2 = [charNum charValue];
    3. NSLog(@"%c", c2);

    是将封装了字符型数据的NSNumber类对象还原成字符型变量值。使用NSNumber类的charValue方法,将NSNumber类对象中封装的整型数据还原。

    步骤三:封装单精度浮点型数据

    代码如下所示:

     
    1. #import <Foundation/Foundation.h>
    2. int main(int argc, const char * argv[])
    3. {
    4. @autoreleasepool {
    5. // insert code here...
    6. int i = 10;
    7. //装箱
    8. NSNumber* intNum = [NSNumber numberWithInt:i];
    9. //拆箱
    10. int i2 = [intNum intValue];
    11. NSLog(@"%d", i2);
    12. char c = 'a';
    13. //装箱
    14. NSNumber* charNum = [NSNumber numberWithChar:c];
    15. //拆箱
    16. char c2 = [charNum charValue];
    17. NSLog(@"%c", c2);
    18. float f = 3.14f;
    19. //装箱
    20. NSNumber* floatNum = [NSNumber numberWithFloat:f];
    21. //拆箱
    22. float f2 = [floatNum floatValue];
    23. NSLog(@"%f", f2);
    24. }
    25. return 0;
    26. }

    在上述代码中,以下代码:

     
    1. float f = 3.14f;
    2. //装箱
    3. NSNumber* floatNum = [NSNumber numberWithFloat:f];

    将单精度浮点型变量f封装成NSNumber类的对象。封装的过程是使用NSNumber类的方法numberWithFloat,该方法带有一个实参,是要封装的单精度浮点型变量。返回值是封装好的NSNumber类的对象。

    在上述代码中,以下代码:

    1. //拆箱
    2. float f2 = [floatNum floatValue];
    3. NSLog(@"%f", f2);

    是将封装了单精度浮点型数据的NSNumber类对象还原成单精度浮点型变量值。使用NSNumber类的floatValue方法,将NSNumber类对象中封装的整型数据还原。

    步骤四:封装双精度浮点型数据

    代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. int main(int argc, const char * argv[])
    3. {
    4. @autoreleasepool {
    5. // insert code here...
    6. int i = 10;
    7. //装箱
    8. NSNumber* intNum = [NSNumber numberWithInt:i];
    9. //拆箱
    10. int i2 = [intNum intValue];
    11. NSLog(@"%d", i2);
    12. char c = 'a';
    13. //装箱
    14. NSNumber* charNum = [NSNumber numberWithChar:c];
    15. //拆箱
    16. char c2 = [charNum charValue];
    17. NSLog(@"%c", c2);
    18. float f = 3.14f;
    19. //装箱
    20. NSNumber* floatNum = [NSNumber numberWithFloat:f];
    21. //拆箱
    22. float f2 = [floatNum floatValue];
    23. NSLog(@"%f", f2);
    24. double d = 3.1415926;
    25. //装箱
    26. NSNumber* doubleNum = [NSNumber numberWithDouble:d];
    27. //拆箱
    28. double d2 = [doubleNum doubleValue];
    29. NSLog(@"%lf", d2);
    30. }
    31. return 0;
    32. }

    在上述代码中,以下代码:

    1. double d = 3.1415926;
    2. //装箱
    3. NSNumber* doubleNum = [NSNumber numberWithDouble:d];

    将双精度浮点型变量d封装成NSNumber类的对象。封装的过程是使用NSNumber类的方法numberWithDouble,该方法带有一个实参,是要封装的双精度浮点型变量。返回值是封装好的NSNumber类的对象。

    在上述代码中,以下代码:

    1. //拆箱
    2. double d2 = [doubleNum doubleValue];
    3. NSLog(@"%lf", d2);

    是将封装了双精度浮点型数据的NSNumber类对象还原成双精度浮点型变量值。使用NSNumber类的doubleValue方法,将NSNumber类对象中封装的整型数据还原。

    1.3 完整代码

    本案例的完整代码如下:

    1. #import <Foundation/Foundation.h>
    2. int main(int argc, const char * argv[])
    3. {
    4. @autoreleasepool {
    5. // insert code here...
    6. int i = 10;
    7. //装箱
    8. NSNumber* intNum = [NSNumber numberWithInt:i];
    9. //拆箱
    10. int i2 = [intNum intValue];
    11. NSLog(@"%d", i2);
    12. char c = 'a';
    13. //装箱
    14. NSNumber* charNum = [NSNumber numberWithChar:c];
    15. //拆箱
    16. char c2 = [charNum charValue];
    17. NSLog(@"%c", c2);
    18. float f = 3.14f;
    19. //装箱
    20. NSNumber* floatNum = [NSNumber numberWithFloat:f];
    21. //拆箱
    22. float f2 = [floatNum floatValue];
    23. NSLog(@"%f", f2);
    24. double d = 3.1415926;
    25. //装箱
    26. NSNumber* doubleNum = [NSNumber numberWithDouble:d];
    27. //拆箱
    28. double d2 = [doubleNum doubleValue];
    29. NSLog(@"%lf", d2);
    30. }
    31. return 0;
    32. }

    2 根据身份证号码求年龄

    2.1 问题

    身份证是公民用于证明持有人身份的证件

    1984年4月,我国开始实行居民身份证制度,第一代居民身份证采用印刷和照相翻拍技术塑封而成,比较容易被伪造。

    2003年6月,《中华人民共和国居民身份证法》规定居住在中华人民共和国境内的年满十六周岁的中国公民,应当申请领取居民身份证;未满十六周岁的中国公民,也可以依照本法的规定申请领取居民身份证。

    2004年3月起我国正式开始为居民换发内藏非接触式IC卡智能芯片的第二代居民身份证,第二代身份证表面采用防伪膜和印刷防伪技术,使用个人彩色照片,而且内置了数字芯片,采用了数字防伪措施,存有个人图像和信息,可以用机器读取。十六周岁至二十五周岁的,发给有效期十年的居民身份证;二十六周岁至四十五周岁的,发给有效期二十年的居民身份证;四十六周岁以上的,发给长期有效的居民身份证;未满十六周岁的公民,自愿申请领取居民身份证的,发给有效期五年的居民身份证。

    自2012年1月1日起,公民申请领取、换领、补领居民身份证,应当登记指纹信息。

    2.2 方案

    身份证上有一个18位的身份证号,这个号码依据《中华人民共和国国家标准 GB 11643-1999》是这样定义的,从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。出生日期码表示持证人出生的年、月、日。

    依据以上的知识,截取身份证号码的出生日期码,在从中得到出生的年份值与今年相减就可以得到年龄。

    2.3 步骤

    实现此案例需要按照如下步骤进行。

    步骤一:从控制台输入某人的身份证号

    代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. int main(int argc, const char * argv[])
    3. {
    4. @autoreleasepool {
    5. // insert code here...
    6. //从控制台输入一个身份证号
    7. char id[19] = {};
    8. NSLog(@"请输入身份证号:");
    9. scanf("%s", id);
    10. NSString *sid = [NSString stringWithCString:id encoding:NSASCIIStringEncoding];
    11. }
    12. return 0;
    13. }

    上述代码中,以下代码:

    1. NSString *fileName = [NSString stringWithCString:name encoding:NSASCIIStringEncoding];

    是使用NSString类的stringWithCString: encoding:方法,将字符数组name转换成NSString类的对象。stringWithCString: encoding:方法有两个实参,第一个实参是要转换的字符数组名;第二个实参为要转换字符数组的编码方式,对于char型数组,编码方式为NSASCIIStringEncoding。

    步骤二:截取身份证中的年龄

    代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. int main(int argc, const char * argv[])
    3. {
    4. @autoreleasepool {
    5. // insert code here...
    6. //从控制台输入一个身份证号
    7. char id[19] = {};
    8. NSLog(@"请输入身份证号:");
    9. scanf("%s", id);
    10. NSString *sid = [NSString stringWithCString:id encoding:NSASCIIStringEncoding];
    11. //得到身份证号中的年龄
    12. NSRange ryear = {6,4};
    13. NSString* year = [sid substringWithRange:ryear];
    14. }
    15. return 0;
    16. }

    上述代码中,以下代码:

    1. NSRange ryear = {6,4};

    定义一个范围ryear,在本案例中这个范围的意义是,从身份证号码第7位开始,连续4个数字。程序中是6,因为字符串中的字符从0开始计算,所以到6时是第7位。

    上述代码中,以下代码:

    1. NSString* year = [sid substringWithRange:ryear];

    是截取身份证字符串指定范围内的数字,使用NSString类的substringWithRange方法实现,该方法带有一个实参ryear,是要截取身份证号码从第7位开始,连续4个数字,它们正好是持证人的出生年份值。

    步骤三:获得当前日期

    代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. int main(int argc, const char * argv[])
    3. {
    4. @autoreleasepool {
    5. // insert code here...
    6. //从控制台输入一个身份证号
    7. char id[19] = {};
    8. NSLog(@"请输入身份证号:");
    9. scanf("%s", id);
    10. NSString *sid = [NSString stringWithCString:id encoding:NSASCIIStringEncoding];
    11. //得到身份证号中的年龄
    12. NSRange ryear = {6,4};
    13. NSString* year = [sid substringWithRange:ryear];
    14. //得到当前日期
    15. NSDate* now3 = [NSDate date];
    16. NSDateFormatter* format = [[NSDateFormatter alloc]init];
    17. format.dateFormat = @"yyyy";
    18. NSString* syear=[format stringFromDate:now3];
    19. }
    20. return 0;
    21. }

    上述代码中,以下代码:

    1. NSDate* now3 = [NSDate date];

    是获取当前日期值。类NSDate中存储着时间信息,通过工厂方法date,可以创建一个NSDate类的对象,该对象中是当前时间值。

    上述代码中,以下代码:

    1. NSDateFormatter* format = [[NSDateFormatter alloc]init];
    2. format.dateFormat = @"yyyy";

    定义一个日期模板对象format,然后使用该对象中的format.dateFormat属性指定日期的格式。

    上述代码中,以下代码:

    1. NSString* syear=[format stringFromDate:now3];

    是根据日期模板对象format的format.dateFormat日期格式属性,使用NSDateFormatter类的stringFromDate方法,获取对象now3中的当前年份,stringFromDate方法的返回值为NSString类的对象。

    步骤四:将字符串类型转换成数值

    代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. int main(int argc, const char * argv[])
    3. {
    4. @autoreleasepool {
    5. // insert code here...
    6. //从控制台输入一个身份证号
    7. char id[19] = {};
    8. NSLog(@"请输入身份证号:");
    9. scanf("%s", id);
    10. NSString *sid = [NSString stringWithCString:id encoding:NSASCIIStringEncoding];
    11. //得到身份证号中的年龄
    12. NSRange ryear = {6,4};
    13. NSString* year = [sid substringWithRange:ryear];
    14. //得到当前日期
    15. NSDate* now3 = [NSDate date];
    16. NSDateFormatter* format = [[NSDateFormatter alloc]init];
    17. format.dateFormat = @"yyyy";
    18. NSString* syear=[format stringFromDate:now3];
    19. //将相应的字符串类型转换成数值
    20. int iyear2 = [year intValue];
    21. int syear2 = [syear intValue];
    22. }
    23. return 0;
    24. }

    上述代码中,以下代码:

    1. int iyear2 = [year intValue];
    2. int syear2 = [syear intValue];

    使用NSString类的方法intValue,将字符串中的数字字符转换成整型数值。

    步骤五:计算年龄

    代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. int main(int argc, const char * argv[])
    3. {
    4. @autoreleasepool {
    5. // insert code here...
    6. //从控制台输入一个身份证号
    7. char id[19] = {};
    8. NSLog(@"请输入身份证号:");
    9. scanf("%s", id);
    10. NSString *sid = [NSString stringWithCString:id encoding:NSASCIIStringEncoding];
    11. //得到身份证号中的年龄
    12. NSRange ryear = {6,4};
    13. NSString* year = [sid substringWithRange:ryear];
    14. //得到当前日期
    15. NSDate* now3 = [NSDate date];
    16. NSDateFormatter* format = [[NSDateFormatter alloc]init];
    17. format.dateFormat = @"yyyy";
    18. NSString* syear=[format stringFromDate:now3];
    19. //将相应的字符串类型转换成数值
    20. int iyear2 = [year intValue];
    21. int syear2 = [syear intValue];
    22. //计算年龄
    23. int age = syear2-iyear2;
    24. NSLog(@"身份证:%@ ->年龄:%d",sid,age);
    25. }
    26. return 0;
    27. }

    上述代码中,以下代码:

    1. int age = syear2-iyear2;

    用今年的年份值减去身份证上的年份值,即可得到持证人的年龄。

    2.4 完整代码

    本案例的完整代码如下:

    1. #import <Foundation/Foundation.h>
    2. int main(int argc, const char * argv[])
    3. {
    4. @autoreleasepool {
    5. // insert code here...
    6. //从控制台输入一个身份证号
    7. char id[19] = {};
    8. NSLog(@"请输入身份证号:");
    9. scanf("%s", id);
    10. NSString *sid = [NSString stringWithCString:id encoding:NSASCIIStringEncoding];
    11. //得到身份证号中的年龄
    12. NSRange ryear = {6,4};
    13. NSString* year = [sid substringWithRange:ryear];
    14. //得到当前日期
    15. NSDate* now3 = [NSDate date];
    16. NSDateFormatter* format = [[NSDateFormatter alloc]init];
    17. format.dateFormat = @"yyyy";
    18. NSString* syear=[format stringFromDate:now3];
    19. //将相应的字符串类型转换成数值
    20. int iyear2 = [year intValue];
    21. int syear2 = [syear intValue];
    22. //计算年龄
    23. int age = syear2-iyear2;
    24. NSLog(@"身份证:%@ ->年龄:%d",sid,age);
    25. }
    26. return 0;
    27. }

    3 向数组中存放数据

    3.1 问题

    现在有一些数据,它们是整型数据10、字符型数据‘a’、单精度浮点型数据10.1f和自定义类TRStudent的一个对象,将它们存放在数组NSArray中。

    3.2 步骤

    实现此案例需要按照如下步骤进行。

    步骤一:将基本数据类型数据封装

    代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. int main(int argc, const char * argv[])
    3. {
    4. @autoreleasepool {
    5. // insert code here...
    6. //整型数据
    7. int i = 10;
    8. NSNumber* oi = [NSNumber numberWithInt:i];
    9. //字符型数据
    10. char c = 'a';
    11. NSNumber* oc = [NSNumber numberWithChar:c];
    12. //单精度浮点型数据
    13. float f = 10.1f;
    14. NSNumber* of = [NSNumber numberWithFloat:f];
    15. }
    16. return 0;
    17. }

    步骤二:定义类TRStudent

    首先,在Day02-3工程中新添加TRStudent.h文件,用于定义新的类TRStudent。

    代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. @interface TRStudent : NSObject
    3. @property(nonatomic,assign)int age;
    4. @property(nonatomic,copy)NSString* name;
    5. @end

    在上述代码中,以下代码:

    1. @property(nonatomic,assign)int age;
    2. @property(nonatomic,copy)NSString* name;

    在TRStudent类中定义了两个属性,一个是整型变量age,用于存储学生的年龄;另一个是NSString类的对象name,用于存储学生的姓名。

    然后,在类TRStudent的实现部分,即在TRStudent.m文件中,重写description方法的实现,该方法用于在NSLog中用%@输出TRStudent类的对象值。

    代码如下所示:

    1. #import "TRStudent.h"
    2. @implementation TRStudent
    3. -(NSString *)description{
    4. return [NSString stringWithFormat:@"name:%@ age:%d",self.name, self.age];
    5. }
    6. @end

    步骤三:在主程序中创建TRStudent类的对象

    代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. #import "TRStudent.h"
    3. int main(int argc, const char * argv[])
    4. {
    5. @autoreleasepool {
    6. // insert code here...
    7. //整型数据
    8. int i = 10;
    9. NSNumber* oi = [NSNumber numberWithInt:i];
    10. //字符型数据
    11. char c = 'a';
    12. NSNumber* oc = [NSNumber numberWithChar:c];
    13. //单精度浮点型数据
    14. float f = 10.1f;
    15. NSNumber* of = [NSNumber numberWithFloat:f];
    16. //类TRSTudent
    17. TRStudent* stu = [[TRStudent alloc]init];
    18. stu.age = 18;
    19. stu.name = @"zhangsan";
    20. }
    21. return 0;
    22. }

    步骤四:将数据存入数组

    代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. #import "TRStudent.h"
    3. int main(int argc, const char * argv[])
    4. {
    5. @autoreleasepool {
    6. // insert code here...
    7. //整型数据
    8. int i = 10;
    9. NSNumber* oi = [NSNumber numberWithInt:i];
    10. //字符型数据
    11. char c = 'a';
    12. NSNumber* oc = [NSNumber numberWithChar:c];
    13. //单精度浮点型数据
    14. float f = 10.1f;
    15. NSNumber* of = [NSNumber numberWithFloat:f];
    16. //类TRSTudent
    17. TRStudent* stu = [[TRStudent alloc]init];
    18. stu.age = 18;
    19. stu.name = @"zhangsan";
    20. //将以上数据存放在数组中
    21. NSArray* array4 = [NSArray arrayWithObjects:oi,oc,of,stu, nil];
    22. for (int i=0; i<[array4 count]; i++) {
    23. id obj = [array4 objectAtIndex:i];
    24. NSLog(@"obj:%@",obj);
    25. }
    26. }
    27. return 0;
    28. }

    上述代码中,以下代码:

    1. NSArray* array4 = [NSArray arrayWithObjects:oi,oc,of,stu, nil];

    是用前面生成的数据,创建NSArray类的对象array4。NSArray类的工厂方法arrayWithObjects:用于生成NSArray类的对象,实参是要放入数组的数据,值得注意的是在这些数据的最后需要加上nil,表示要放入的数据已经结束。

    上述代码中,以下代码:

    1. for (int i=0; i<[array4 count]; i++) {
    2. id obj = [array4 objectAtIndex:i];
    3. NSLog(@"obj:%@",obj);
    4. }

    是设置一个循环来遍历数组。NSArray类的方法count返回对象array4中的数组元素个数,在这里用于限定循环的次数。NSArray类的方法objectAtIndex:返回指定位置的数组元素值,实参i用于指定要返回哪个数组元素。因为数组中存储的是不同数据类型的数据,所以需要用id类型的指针来接收。最后,在NSLog中使用格式符%@来输出数组中的元素。%@专用于输出类的对象,该格式符在输出自定义类TRStudent时,会调用TRStudent类中重写的description方法。

    3.3 完整代码

    本案例中,类TRStudent声明,即TRStudent.h文件,完整代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. @interface TRStudent : NSObject
    3. @property(nonatomic,assign)int age;
    4. @property(nonatomic,copy)NSString* name;
    5. @end

    类TRStudent实现,即TRStudent.m文件,完整代码如下所示:

    1. #import "TRStudent.h"
    2. @implementation TRStudent
    3. -(NSString *)description{
    4. return [NSString stringWithFormat:@"name:%@ age:%d",self.name, self.age];
    5. }
    6. @end

    主程序,即main.m,完整代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. #import "TRStudent.h"
    3. int main(int argc, const char * argv[])
    4. {
    5. @autoreleasepool {
    6. // insert code here...
    7. //整型数据
    8. int i = 10;
    9. NSNumber* oi = [NSNumber numberWithInt:i];
    10. //字符型数据
    11. char c = 'a';
    12. NSNumber* oc = [NSNumber numberWithChar:c];
    13. //单精度浮点型数据
    14. float f = 10.1f;
    15. NSNumber* of = [NSNumber numberWithFloat:f];
    16. //类TRSTudent
    17. TRStudent* stu = [[TRStudent alloc]init];
    18. stu.age = 18;
    19. stu.name = @"zhangsan";
    20. //将以上数据存放在数组中
    21. NSArray* array4 = [NSArray arrayWithObjects:oi,oc,of,stu, nil];
    22. for (int i=0; i<[array4 count]; i++) {
    23. id obj = [array4 objectAtIndex:i];
    24. NSLog(@"obj:%@",obj);
    25. }
    26. }
    27. return 0;
    28. }

    4 创建五个学生对象,按姓名排序。

    4.1 问题

    创建一个自定义类TRStudent,为该类生成五个对象。把这五个对象存入一个数组当中,然后按照姓名对五个对象进行排序。

    4.2 步骤

    实现此案例需要按照如下步骤进行。

    步骤一:定义类TRStudent

    首先,在Day02-4工程中新添加TRStudent.h文件,用于定义新的类TRStudent。

    代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. @interface TRStudent : NSObject
    3. @property(nonatomic,assign)int age;
    4. @property(nonatomic,copy)NSString* name;
    5. -(id)initWithAge:(int)age andName:(NSString*)name;
    6. //定义对象的比较规则
    7. -(NSComparisonResult)compare:(TRStudent*)otherStu;
    8. @end

    在上述代码中,以下代码:

    1. @property(nonatomic,assign)int age;
    2. @property(nonatomic,copy)NSString* name;

    在TRStudent类中定义了两个属性,一个是整型变量age,用于存储学生的年龄;另一个是NSString类的对象name,用于存储学生的姓名。

    在上述代码中,以下代码:

    1. -(id)initWithAge:(int)age andName:(NSString*)name;

    声明了TRStudent类的带参初始化函数。

    在上述代码中,以下代码:

    1. //定义对象的比较规则
    2. -(NSComparisonResult)compare:(TRStudent*)otherStu;

    声明了TRStudent类对象的比较规则方法,该方法用于当TRStudent类对象进行排序时,哪个对象在前,哪个对象在后的评判标准。

    然后,在类TRStudent的实现部分,即在TRStudent.m文件中,实现了compare方法和带参初始化方法,重写description方法的实现。

    代码如下所示:

    1. #import "TRStudent.h"
    2. @implementation TRStudent
    3. //按姓名排序
    4. -(NSComparisonResult)compare:(TRStudent*)otherStu{
    5. return [self.name compare:otherStu.name];
    6. }
    7. -(id)initWithAge:(int)age andName:(NSString*)name{
    8. self = [super init];
    9. if (self) {
    10. self.age = age;
    11. self.name = name;
    12. }
    13. return self;
    14. }
    15. -(NSString *)description{
    16. return [NSString stringWithFormat:@"student age:%d name:%@",self.age,self.name];
    17. }
    18. @end

    上述代码中,以下代码:

    1. //按姓名排序
    2. -(NSComparisonResult)compare:(TRStudent*)otherStu{
    3. return [self.name compare:otherStu.name];
    4. }

    是对比较规则方法的实现。在该方法中,有一个形参,传入的是另一个TRStudent类的对象,将该对象与当前对象进行比较。compare:方法有一个返回值,是NSComparisonResult类型的值,该类型的值只有三个,分别是NSOrderedAscending(升序排列)、NSOrderedSame(相等)、NSOrderedDescending(降序排列)。compare:方法的函数体内使用NSString类的compare:方法对两个TRStudent类的对象的name属性进行比较。

    上述代码中,以下代码:

    1. -(id)initWithAge:(int)age andName:(NSString*)name{
    2. self = [super init];
    3. if (self) {
    4. self.age = age;
    5. self.name = name;
    6. }
    7. return self;
    8. }

    是TRStudent类的带参初始化函数的实现。

    上述代码中,以下代码:

    1. -(NSString *)description{
    2. return [NSString stringWithFormat:@"student age:%d name:%@",self.age,self.name];
    3. }

    是重写description方法的实现,该方法用于在NSLog中用%@输出TRStudent类的对象值。

    步骤二:在主程序中定义五个学生对象

    代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. #import "TRStudent.h"
    3. int main(int argc, const char * argv[])
    4. {
    5. @autoreleasepool {
    6. // insert code here...
    7. //定义五个对象
    8. TRStudent* stu = [[TRStudent alloc]initWithAge:18 andName:@"zhangsan"];
    9. TRStudent* stu2 = [[TRStudent alloc]initWithAge:21 andName:@"lisi"];
    10. TRStudent* stu3 = [[TRStudent alloc]initWithAge:20 andName:@"wangwu"];
    11. TRStudent* stu4 = [[TRStudent alloc]initWithAge:25 andName:@"zhaoliu"];
    12. TRStudent* stu5 = [[TRStudent alloc]initWithAge:23 andName:@"qianqi"];
    13. }
    14. return 0;
    15. }

    步骤三:使用五个学生对象生成一个数组

    代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. #import "TRStudent.h"
    3. int main(int argc, const char * argv[])
    4. {
    5. @autoreleasepool {
    6. // insert code here...
    7. //定义五个对象
    8. TRStudent* stu = [[TRStudent alloc]initWithAge:18 andName:@"zhangsan"];
    9. TRStudent* stu2 = [[TRStudent alloc]initWithAge:21 andName:@"lisi"];
    10. TRStudent* stu3 = [[TRStudent alloc]initWithAge:20 andName:@"wangwu"];
    11. TRStudent* stu4 = [[TRStudent alloc]initWithAge:25 andName:@"zhaoliu"];
    12. TRStudent* stu5 = [[TRStudent alloc]initWithAge:23 andName:@"qianqi"];
    13. //生成数组
    14. NSArray* stus = @[stu,stu2,stu3,stu4,stu5];
    15. NSLog(@"stus:%@",stus);
    16. }
    17. return 0;
    18. }

    上述代码中,以下代码:

    1. NSArray* stus = @[stu,stu2,stu3,stu4,stu5];

    是iOS6.0以后定义的生成数组对象的简化方法。

    步骤四:对五个学生对象进行排序

    代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. #import "TRStudent.h"
    3. int main(int argc, const char * argv[])
    4. {
    5. @autoreleasepool {
    6. // insert code here...
    7. //定义五个对象
    8. TRStudent* stu = [[TRStudent alloc]initWithAge:18 andName:@"zhangsan"];
    9. TRStudent* stu2 = [[TRStudent alloc]initWithAge:21 andName:@"lisi"];
    10. TRStudent* stu3 = [[TRStudent alloc]initWithAge:20 andName:@"wangwu"];
    11. TRStudent* stu4 = [[TRStudent alloc]initWithAge:25 andName:@"zhaoliu"];
    12. TRStudent* stu5 = [[TRStudent alloc]initWithAge:23 andName:@"qianqi"];
    13. //生成数组
    14. NSArray* stus = @[stu,stu2,stu3,stu4,stu5];
    15. NSLog(@"stus:%@",stus);
    16. //生成排序后的数组
    17. NSArray* stus2 = [stus sortedArrayUsingSelector:@selector(compare:)];
    18. NSLog(@"stus2:%@",stus2);
    19. }
    20. return 0;
    21. }

    上述代码中,以下代码:

    1. NSArray* stus2 = [stus sortedArrayUsingSelector:@selector(compare:)];

    是调用NSArray类中的sortedArrayUsingSelector方法对stus内的数组元素进行排序,将排序结果生成一个新的数组stus2。sortedArrayUsingSelector方法带有一个实参,是一个方法选择器,该方法选择器指定排序时的比较规则。在本案例中,排序比较规则采用TRStudent类中的compare方法。

    4.3 完整代码

    本案例中,类TRStudent声明,即TRStudent.h文件,完整代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. @interface TRStudent : NSObject
    3. @property(nonatomic,assign)int age;
    4. @property(nonatomic,copy)NSString* name;
    5. -(id)initWithAge:(int)age andName:(NSString*)name;
    6. //定义对象的比较规则
    7. -(NSComparisonResult)compare:(TRStudent*)otherStu;
    8. @end

    类TRStudent实现,即TRStudent.m文件,完整代码如下所示:

    1. #import "TRStudent.h"
    2. @implementation TRStudent
    3. //按姓名排序
    4. -(NSComparisonResult)compare:(TRStudent*)otherStu{
    5. return [self.name compare:otherStu.name];
    6. }
    7. -(id)initWithAge:(int)age andName:(NSString*)name{
    8. self = [super init];
    9. if (self) {
    10. self.age = age;
    11. self.name = name;
    12. }
    13. return self;
    14. }
    15. -(NSString *)description{
    16. return [NSString stringWithFormat:@"student age:%d name:%@",self.age,self.name];
    17. }
    18. @end

    主程序,即main.m,完整代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. #import "TRStudent.h"
    3. int main(int argc, const char * argv[])
    4. {
    5. @autoreleasepool {
    6. // insert code here...
    7. //定义五个对象
    8. TRStudent* stu = [[TRStudent alloc]initWithAge:18 andName:@"zhangsan"];
    9. TRStudent* stu2 = [[TRStudent alloc]initWithAge:21 andName:@"lisi"];
    10. TRStudent* stu3 = [[TRStudent alloc]initWithAge:20 andName:@"wangwu"];
    11. TRStudent* stu4 = [[TRStudent alloc]initWithAge:25 andName:@"zhaoliu"];
    12. TRStudent* stu5 = [[TRStudent alloc]initWithAge:23 andName:@"qianqi"];
    13. //生成数组
    14. NSArray* stus = @[stu,stu2,stu3,stu4,stu5];
    15. NSLog(@"stus:%@",stus);
    16. //生成排序后的数组
    17. NSArray* stus2 = [stus sortedArrayUsingSelector:@selector(compare:)];
    18. NSLog(@"stus2:%@",stus2);
    19. }
    20. return 0;
    21. }
  • 相关阅读:
    OpenGL光栅化作业:【bresenham算法】GL_POINTS为基础画圆
    OpenGL光栅化作业:【bresenham算法】GL_POINTS为基础画线段
    GIT 4 (标签)
    用户组 vim yum
    Git (提交版本及版本回退)
    GIT服务器的搭建
    GIT 2 (工作区,暂存库,版本库对比)
    用户的管理
    文档搜索
    GIT 3 (推送与克隆 及 分支管理)
  • 原文地址:https://www.cnblogs.com/52190112cn/p/5049287.html
Copyright © 2020-2023  润新知