• NSArray(二) 、 NSMutableArray 、 NSSet 、 NSMutableSet


    1 创建五个学生对象,放入数组并遍历

    1.1 问题

    创建一个自定义类TRStudent,为该类生成五个对象。把这五个对象存入一个数组当中,然后遍历数组。

    1.2 步骤

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

    步骤一:定义类TRStudent

    首先,在Day03工程中新添加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:@"age:%d",self.age];
    5. }
    6. @end

    上述代码中,以下代码:

    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. TRStudent* stu = [[TRStudent alloc]init];
    8. stu.age = 18;
    9. stu.name = @"zhangsan";
    10. TRStudent* stu2 = [[TRStudent alloc]init];
    11. stu2.age = 20;
    12. stu2.name = @"lisi";
    13. TRStudent* stu3 = [[TRStudent alloc]init];
    14. stu3.age = 30;
    15. stu3.name = @"wangwu";
    16. TRStudent* stu4 = [[TRStudent alloc]init];
    17. stu4.age = 40;
    18. stu4.name = @"zhaoliu";
    19. TRStudent* stu5 = [[TRStudent alloc]init];
    20. stu5.age = 35;
    21. stu5.name = @"qianqi";
    22. }
    23. return 0;
    24. }

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

    代码如下所示:

    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. TRStudent* stu = [[TRStudent alloc]init];
    8. stu.age = 18;
    9. stu.name = @"zhangsan";
    10. TRStudent* stu2 = [[TRStudent alloc]init];
    11. stu2.age = 20;
    12. stu2.name = @"lisi";
    13. TRStudent* stu3 = [[TRStudent alloc]init];
    14. stu3.age = 30;
    15. stu3.name = @"wangwu";
    16. TRStudent* stu4 = [[TRStudent alloc]init];
    17. stu4.age = 40;
    18. stu4.name = @"zhaoliu";
    19. TRStudent* stu5 = [[TRStudent alloc]init];
    20. stu5.age = 35;
    21. stu5.name = @"qianqi";
    22. NSMutableArray* students = [NSMutableArray arrayWithObjects:stu,stu2,stu3,stu4,stu5, nil];
    23. }
    24. return 0;
    25. }

    上述代码中,以下代码:

    1. NSMutableArray* students = [NSMutableArray arrayWithObjects:stu,stu2,stu3,stu4,stu5, nil];

    生成一个可变数组类NSMutableArray的对象students。并使用NSMutableArray类的方法arrayWithObjects将students初始化为上述五个学生对象。值得注意的是实参的最后是nil,它的作用是标志后面没有要初始化的对象了。

    步骤四:对五个学生对象进行遍历

    代码如下所示:

    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. TRStudent* stu = [[TRStudent alloc]init];
    8. stu.age = 18;
    9. stu.name = @"zhangsan";
    10. TRStudent* stu2 = [[TRStudent alloc]init];
    11. stu2.age = 20;
    12. stu2.name = @"lisi";
    13. TRStudent* stu3 = [[TRStudent alloc]init];
    14. stu3.age = 30;
    15. stu3.name = @"wangwu";
    16. TRStudent* stu4 = [[TRStudent alloc]init];
    17. stu4.age = 40;
    18. stu4.name = @"zhaoliu";
    19. TRStudent* stu5 = [[TRStudent alloc]init];
    20. stu5.age = 35;
    21. stu5.name = @"qianqi";
    22. NSMutableArray* students = [NSMutableArray arrayWithObjects:stu,stu2,stu3,stu4,stu5, nil];
    23. NSLog(@"遍历学生内容..........");
    24. for (int i = 0; i<[students count]; i++) {
    25. TRStudent* stu = [students objectAtIndex:i];
    26. NSLog(@"stu age:%d name:%@",stu.age,stu.name);
    27. }
    28. }
    29. return 0;
    30. }

    上述代码中,以下代码:

    1. for (int i = 0; i<[students count]; i++) {
    2. TRStudent* stu = [students objectAtIndex:i];
    3. NSLog(@"stu age:%d name:%@",stu.age,stu.name);
    4. }

    是设置一个循环来遍历数组。NSMutableArray类的方法count返回对象students中的数组元素个数,在这里用于限定循环的次数。NSMutableArray类的方法objectAtIndex:返回指定位置的数组元素值,实参i用于指定要返回哪个数组元素。最后,使用NSLog在控制台上输出TRStudent类对象的两个属性值。

    1.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:@"age:%d",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. TRStudent* stu = [[TRStudent alloc]init];
    8. stu.age = 18;
    9. stu.name = @"zhangsan";
    10. TRStudent* stu2 = [[TRStudent alloc]init];
    11. stu2.age = 20;
    12. stu2.name = @"lisi";
    13. TRStudent* stu3 = [[TRStudent alloc]init];
    14. stu3.age = 30;
    15. stu3.name = @"wangwu";
    16. TRStudent* stu4 = [[TRStudent alloc]init];
    17. stu4.age = 40;
    18. stu4.name = @"zhaoliu";
    19. TRStudent* stu5 = [[TRStudent alloc]init];
    20. stu5.age = 35;
    21. stu5.name = @"qianqi";
    22. NSMutableArray* students = [NSMutableArray arrayWithObjects:stu,stu2,stu3,stu4,stu5, nil];
    23. NSLog(@"遍历学生内容..........");
    24. for (int i = 0; i<[students count]; i++) {
    25. TRStudent* stu = [students objectAtIndex:i];
    26. NSLog(@"stu age:%d name:%@",stu.age,stu.name);
    27. }
    28. }
    29. return 0;
    30. }

    2 重构学生与学校的练习

    2.1 问题

    本案例要求用集合解决下述问题。问题是:有一个学校,该学校有两个学院,每个学院中又有两个班级,而在每个班级中有两名学生。

    现在作如下要求:

    1)显示所有学生的信息。

    2)只显示姓名为“zhangsan”的学生的信息。

    3)只显示年龄为18岁的学生的信息。

    4)如果每个学生有本书,显示所有学生的书的名称和价格。

    2.2 步骤

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

    步骤一:定义类Book

    首先,在Day03-2工程中新添加Book.h文件,用于定义新的类Book。

    代码如下所示:

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

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

    1. @interface Book : NSObject<NSCopying>

    定义了类Book,该类采用了NSCopying协议。

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

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

    在Book类中定义了两个属性,一个是NSString类的对象name,用于存储书的名字;另一个是整型变量price,用于存储书的价格。

    然后,在类Book的实现部分,即在Book.m文件中,添加两个方法的实现,一个是copyWithZone方法,该方法是在NSCopying协议中声明的方法,用于深拷贝;另一个是dealloc方法,由于使用ARC,该方法在本类中实际上没有任何实际意义,只是在类的对象销毁时,在控制台上输出一个提示。

    代码如下所示:

    1. #import "Book.h"
    2. @implementation Book
    3. -(id)copyWithZone:(NSZone*)zone
    4. {
    5. Book* book = [[Book allocWithZone:zone] init];
    6. book.name = self.name;
    7. book.price = self.price;
    8. return book;
    9. }
    10. -(void)dealloc{
    11. NSLog(@"书对象销毁了 price:%d",self.price);
    12. }
    13. @end

    上述代码中,copyWithZone方法不能在类外直接被调用,它是在向一个对象发送copy消息时,由copy消息调用。在该方法中,以下代码:

    1. Book* book = [[Book allocWithZone:zone] init];
    2. book.name = self.name;
    3. book.price = self.price;

    生成一个本类对象的副本。需要注意的是分配空间使用的是allocWithZone方法。

    上述代码中,dealloc方法也不能在类外直接被调用,它是在一个对象被release并且对象的引用计数为0时,由内存管理程序调用的方法。

    步骤二:定义类TRStudent

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

    代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. #import "Book.h"
    3. @interface TRStudent : NSObject
    4. @property(nonatomic,assign)int age;
    5. @property(nonatomic,copy)NSString* name;
    6. @property(nonatomic,copy)Book *book;
    7. -(id)initWithAge:(int)age andName:(NSString*)name andBook:(Book*)book;
    8. +(id)studentWithAge:(int)age andName:(NSString*)name andBook:(Book*)book;
    9. -(void)print:(id)condition;
    10. @end

    在上述代码中,定义了类Student,在类中有三个带参属性。

    一个属性是整型变量age,如下代码所示:

    1. @property(nonatomic,assign) int age;

    用于存储学生的年龄。它有两个参数,一个是nonatomic,它代表对属性赋值的时候不加锁,即在多线程环境下访问时可能会出现数据错误,如果需要在多线程环境下运行,为保证数据不会出现错误,可使用atomic参数,它会在对属性赋值的时候加锁。另一个参数是assign,对于C语言的基本数据类型,只能选取这个参数。

    另一个属性是name,如下代码所示:

    1. @property(nonatomic,copy)NSString* name;

    用于存储学生的姓名。它有两个参数,一个是nonatomic,另一个参数是copy,该参数一般用于NSObject类及其子类的对象,这些对象在赋值时实现深拷贝,即属性name指向的对象是赋值给它的对象的副本。

    最后一个属性是book,如下代码所示:

    1. @property(nonatomic,copy)Book *book;

    用于存储学生正在学习的书。值得注意的是,Book类采纳NSCopying协议,是因为此处使用了copy这个属性参数。

    上述代码中,以下代码:

    1. -(id)initWithAge:(int)age andName:(NSString*)name andBook:(Book*)book;
    2. +(id)studentWithAge:(int)age andName:(NSString*)name andBook:(Book*)book;

    声明了TRStudent类的带参初始化方法和带参工厂方法。

    上述代码中,以下代码:

    1. -(void)print:(id)condition;

    声明了一个print方法,该方法用于根据形参condition的不同,打印不同的TRStudent类对象的属性值。

    然后,在类Student的实现部分,即在Student.m文件中,添加带参初始化方法和工厂初始化方法以及print方法的实现。

    代码如下所示:

    1. #import "TRStudent.h"
    2. @implementation TRStudent
    3. -(id)initWithAge:(int)age
    4. andName:(NSString*)name
    5. andBook:(Book*)book{
    6. self = [super init];
    7. if (self) {
    8. self.age = age;
    9. self.name = name;
    10. self.book = book;
    11. }
    12. return self;
    13. }
    14. +(id)studentWithAge:(int)age
    15. andName:(NSString*)name
    16. andBook:(Book*)book{
    17. return [[TRStudent alloc]initWithAge:age andName:name andBook:book];
    18. }
    19. -(void)print:(id)condition
    20. {
    21. bool a = [condition isKindOfClass:[NSNumber class]];
    22. bool b = [condition intValue] == self.age;
    23. bool c = [condition isKindOfClass:[NSString class]];
    24. bool d = [self.name isEqualToString:condition];
    25. if ((a && b) || (c && d))
    26. NSLog(@"stu name:%@, age:%d", self.name, self.age);
    27. }
    28. @end

    上述代码中,以下代码:

    1. bool a = [condition isKindOfClass:[NSNumber class]];
    2. bool b = [condition intValue] == self.age;

    定义了两个bool类型的变量。

    变量a被赋值为形参condition是否是NSNumber类对象的判断结果,其中方法isKindOfClass的作用是判断对象condition是否是NSNumber类的对象。方法isKindOfClass的形参为Class类型的值,该类型的值通过工厂方法class获得。

    变量b被赋值为形参condition的值是否与当前对象age属性值相等的判断结果。通过向形参condition发送intValue消息,如果condition的值为数字字符串,则将其转换成整型数据。

    上述代码中,以下代码:

    1. bool c = [condition isKindOfClass:[NSString class]];
    2. bool d = [self.name isEqualToString:condition];

    定义了两个bool类型的变量。

    变量c被赋值为形参condition是否是NSString类对象的判断结果。

    变量d被赋值为当前对象name属性值是否与形参condition的值相等的判断结果。方法isEqualToString是NSString类的方法,用于判断两个字符串是否相等。

    上述代码中,以下代码:

    1. if ((a && b) || (c && d))
    2. NSLog(@"stu name:%@, age:%d", self.name, self.age);

    如果条件(a && b)为真则表示形参condition为NSNumber类的对象并且将其拆箱后的值与当前对象age属性值相等。

    如果条件(c && d)为真则表示形参condition为NSString类的对象并且与当前对象name属性值是同一字符串。

    步骤三:在主程序中创建八个学生对象

    代码如下所示:

    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. Book* book1 = [[Book alloc] init];
    9. book1.name = @"sanguo";
    10. book1.price = 20;
    11. TRStudent* stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan" andBook:book1];
    12. Book* book2 = [[Book alloc] init];
    13. book2.name = @"shuihu";
    14. book2.price = 18;
    15. TRStudent* stu2 = [TRStudent studentWithAge:19 andName:@"lisi" andBook:book2];
    16. Book* book3 = [[Book alloc] init];
    17. book3.name = @"xiyouji";
    18. book3.price = 28;
    19. TRStudent* stu3 = [TRStudent studentWithAge:20 andName:@"wangwu" andBook:book3];
    20. Book* book4 = [[Book alloc] init];
    21. book4.name = @"hongluomeng";
    22. book4.price = 24;
    23. TRStudent* stu4 = [TRStudent studentWithAge:21 andName:@"zhaoliu" andBook:book4];
    24. Book* book5 = [[Book alloc] init];
    25. book5.name = @"fengshenyanyi";
    26. book5.price = 22;
    27. TRStudent* stu5 = [TRStudent studentWithAge:22 andName:@"qianqi" andBook:book5];
    28. Book* book6 = [[Book alloc] init];
    29. book6.name = @"liaozhaizhiyi";
    30. book6.price = 15;
    31. TRStudent* stu6 = [TRStudent studentWithAge:23 andName:@"zhangfei" andBook:book6];
    32. Book* book7 = [[Book alloc] init];
    33. book7.name = @"sanxiawuyi";
    34. book7.price = 17;
    35. TRStudent* stu7 = [TRStudent studentWithAge:24 andName:@"guanyu" andBook:book7];
    36. Book* book8 = [[Book alloc] init];
    37. book8.name = @"yuefeizhuan";
    38. book8.price = 27;
    39. TRStudent* stu8 = [TRStudent studentWithAge:25 andName:@"zhaoyun" andBook:book8];
    40. }
    41. return 0;
    42. }

    上述代码中,以下代码:

    1. //创建学生对象
    2. Book* book1 = [[Book alloc] init];
    3. book1.name = @"sanguo";
    4. book1.price = 20;
    5. TRStudent* stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan" andBook:book1];

    首先创建了一个Book类的对象book1,然后使用工厂方法studentWithAge:andName:andBook:创建TRStudent类的对象stu1。

    步骤四:在主程序中创建班级集合

    代码如下所示:

    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. Book* book1 = [[Book alloc] init];
    9. book1.name = @"sanguo";
    10. book1.price = 20;
    11. TRStudent* stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan" andBook:book1];
    12. Book* book2 = [[Book alloc] init];
    13. book2.name = @"shuihu";
    14. book2.price = 18;
    15. TRStudent* stu2 = [TRStudent studentWithAge:19 andName:@"lisi" andBook:book2];
    16. Book* book3 = [[Book alloc] init];
    17. book3.name = @"xiyouji";
    18. book3.price = 28;
    19. TRStudent* stu3 = [TRStudent studentWithAge:20 andName:@"wangwu" andBook:book3];
    20. Book* book4 = [[Book alloc] init];
    21. book4.name = @"hongluomeng";
    22. book4.price = 24;
    23. TRStudent* stu4 = [TRStudent studentWithAge:21 andName:@"zhaoliu" andBook:book4];
    24. Book* book5 = [[Book alloc] init];
    25. book5.name = @"fengshenyanyi";
    26. book5.price = 22;
    27. TRStudent* stu5 = [TRStudent studentWithAge:22 andName:@"qianqi" andBook:book5];
    28. Book* book6 = [[Book alloc] init];
    29. book6.name = @"liaozhaizhiyi";
    30. book6.price = 15;
    31. TRStudent* stu6 = [TRStudent studentWithAge:23 andName:@"zhangfei" andBook:book6];
    32. Book* book7 = [[Book alloc] init];
    33. book7.name = @"sanxiawuyi";
    34. book7.price = 17;
    35. TRStudent* stu7 = [TRStudent studentWithAge:24 andName:@"guanyu" andBook:book7];
    36. Book* book8 = [[Book alloc] init];
    37. book8.name = @"yuefeizhuan";
    38. book8.price = 27;
    39. TRStudent* stu8 = [TRStudent studentWithAge:25 andName:@"zhaoyun" andBook:book8];
    40. //班级
    41. NSSet* class1403A = [NSSet setWithObjects:stu1,stu2,nil];
    42. NSSet* class1403B = [NSSet setWithObjects:stu3,stu4,nil];
    43. NSSet* class1403C = [NSSet setWithObjects:stu5,stu6,nil];
    44. NSSet* class1403D = [NSSet setWithObjects:stu7,stu8,nil];
    45. }
    46. return 0;
    47. }

    上述代码中,以下代码:

    1. //班级
    2. NSSet* class1403A = [NSSet setWithObjects:stu1,stu2,nil];
    3. NSSet* class1403B = [NSSet setWithObjects:stu3,stu4,nil];
    4. NSSet* class1403C = [NSSet setWithObjects:stu5,stu6,nil];
    5. NSSet* class1403D = [NSSet setWithObjects:stu7,stu8,nil];

    创建了四个集合对象,每个集合对象为一个班级,班级中有两个学生作为集合元素。其中使用工厂方法setWithObjects创建集合对象。值得注意的是,在形参的最后是nil,它代表放入集合中的元素结束。

    步骤五:在主程序中创建学院和学校

    代码如下所示:

    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. Book* book1 = [[Book alloc] init];
    9. book1.name = @"sanguo";
    10. book1.price = 20;
    11. TRStudent* stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan" andBook:book1];
    12. Book* book2 = [[Book alloc] init];
    13. book2.name = @"shuihu";
    14. book2.price = 18;
    15. TRStudent* stu2 = [TRStudent studentWithAge:19 andName:@"lisi" andBook:book2];
    16. Book* book3 = [[Book alloc] init];
    17. book3.name = @"xiyouji";
    18. book3.price = 28;
    19. TRStudent* stu3 = [TRStudent studentWithAge:20 andName:@"wangwu" andBook:book3];
    20. Book* book4 = [[Book alloc] init];
    21. book4.name = @"hongluomeng";
    22. book4.price = 24;
    23. TRStudent* stu4 = [TRStudent studentWithAge:21 andName:@"zhaoliu" andBook:book4];
    24. Book* book5 = [[Book alloc] init];
    25. book5.name = @"fengshenyanyi";
    26. book5.price = 22;
    27. TRStudent* stu5 = [TRStudent studentWithAge:22 andName:@"qianqi" andBook:book5];
    28. Book* book6 = [[Book alloc] init];
    29. book6.name = @"liaozhaizhiyi";
    30. book6.price = 15;
    31. TRStudent* stu6 = [TRStudent studentWithAge:23 andName:@"zhangfei" andBook:book6];
    32. Book* book7 = [[Book alloc] init];
    33. book7.name = @"sanxiawuyi";
    34. book7.price = 17;
    35. TRStudent* stu7 = [TRStudent studentWithAge:24 andName:@"guanyu" andBook:book7];
    36. Book* book8 = [[Book alloc] init];
    37. book8.name = @"yuefeizhuan";
    38. book8.price = 27;
    39. TRStudent* stu8 = [TRStudent studentWithAge:25 andName:@"zhaoyun" andBook:book8];
    40. //班级
    41. NSSet* class1403A = [NSSet setWithObjects:stu1,stu2,nil];
    42. NSSet* class1403B = [NSSet setWithObjects:stu3,stu4,nil];
    43. NSSet* class1403C = [NSSet setWithObjects:stu5,stu6,nil];
    44. NSSet* class1403D = [NSSet setWithObjects:stu7,stu8,nil];
    45. //学院
    46. NSSet* college3G = [NSSet setWithObjects:class1403A,class1403B,nil];
    47. NSSet* collegeTest = [NSSet setWithObjects:class1403C,class1403D,nil];
    48. //学校
    49. NSSet* tarena = [NSSet setWithObjects:college3G,collegeTest,nil];
    50. }
    51. return 0;
    52. }

    上述代码中,以下代码:

    1. //学院
    2. NSSet* college3G = [NSSet setWithObjects:class1403A,class1403B,nil];
    3. NSSet* collegeTest = [NSSet setWithObjects:class1403C,class1403D,nil];
    4. //学校
    5. NSSet* tarena = [NSSet setWithObjects:college3G,collegeTest,nil];

    创建了两个学院集合,每个学院集合中有两个班级集合作为集合元素。还创建了一个学校集合,其中包含上述两个学院集合作为集合元素。

    步骤六:在主程序中遍历输出所有学生信息

    代码如下所示:

    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. Book* book1 = [[Book alloc] init];
    9. book1.name = @"sanguo";
    10. book1.price = 20;
    11. TRStudent* stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan" andBook:book1];
    12. Book* book2 = [[Book alloc] init];
    13. book2.name = @"shuihu";
    14. book2.price = 18;
    15. TRStudent* stu2 = [TRStudent studentWithAge:19 andName:@"lisi" andBook:book2];
    16. Book* book3 = [[Book alloc] init];
    17. book3.name = @"xiyouji";
    18. book3.price = 28;
    19. TRStudent* stu3 = [TRStudent studentWithAge:20 andName:@"wangwu" andBook:book3];
    20. Book* book4 = [[Book alloc] init];
    21. book4.name = @"hongluomeng";
    22. book4.price = 24;
    23. TRStudent* stu4 = [TRStudent studentWithAge:21 andName:@"zhaoliu" andBook:book4];
    24. Book* book5 = [[Book alloc] init];
    25. book5.name = @"fengshenyanyi";
    26. book5.price = 22;
    27. TRStudent* stu5 = [TRStudent studentWithAge:22 andName:@"qianqi" andBook:book5];
    28. Book* book6 = [[Book alloc] init];
    29. book6.name = @"liaozhaizhiyi";
    30. book6.price = 15;
    31. TRStudent* stu6 = [TRStudent studentWithAge:23 andName:@"zhangfei" andBook:book6];
    32. Book* book7 = [[Book alloc] init];
    33. book7.name = @"sanxiawuyi";
    34. book7.price = 17;
    35. TRStudent* stu7 = [TRStudent studentWithAge:24 andName:@"guanyu" andBook:book7];
    36. Book* book8 = [[Book alloc] init];
    37. book8.name = @"yuefeizhuan";
    38. book8.price = 27;
    39. TRStudent* stu8 = [TRStudent studentWithAge:25 andName:@"zhaoyun" andBook:book8];
    40. //班级
    41. NSSet* class1403A = [NSSet setWithObjects:stu1,stu2,nil];
    42. NSSet* class1403B = [NSSet setWithObjects:stu3,stu4,nil];
    43. NSSet* class1403C = [NSSet setWithObjects:stu5,stu6,nil];
    44. NSSet* class1403D = [NSSet setWithObjects:stu7,stu8,nil];
    45. //学院
    46. NSSet* college3G = [NSSet setWithObjects:class1403A,class1403B,nil];
    47. NSSet* collegeTest = [NSSet setWithObjects:class1403C,class1403D,nil];
    48. //学校
    49. NSSet* tarena = [NSSet setWithObjects:college3G,collegeTest,nil];
    50. //遍历学校
    51. for (NSSet* college in tarena)
    52. {
    53. //遍历学院
    54. for (NSSet* class in college)
    55. {
    56. //遍历班级
    57. for (TRStudent* stu in class)
    58. {
    59. NSLog(@"stu name:%@, age:%d", stu.name, stu.age);
    60. }
    61. }
    62. }
    63. }
    64. return 0;
    65. }

    上述代码中,以下代码:

    1. //遍历学校
    2. for (NSSet* college in tarena)
    3. {
    4. //遍历学院
    5. for (NSSet* class in college)
    6. {
    7. //遍历班级
    8. for (TRStudent* stu in class)
    9. {
    10. NSLog(@"name:%@, age:%d", stu.name, stu.age);
    11. }
    12. }
    13. }

    通过三重快速遍历方法遍历所有学生的信息。以下代码:

    1. //遍历学校
    2. for (NSSet* college in tarena)

    是遍历学校tarena。每次从集合tarena中取出一个元素,放入college中,因为学校集合tarena内的元素为两个学院集合,所以college的数据类型为NSSet*。

    以下代码:

    1. //遍历学院
    2. for (NSSet* class in college)

    是遍历学院college。每次从集合college中取出一个元素,放入class中,因为学院集合college内的元素为两个班级集合,所以class的数据类型为NSSet*。

    以下代码:

    1. //遍历班级
    2. for (TRStudent* stu in class)

    是遍历班级class。因为班级集合class中是两个学生类TRStudent的对象,所以stu的数据类型为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. Book* book1 = [[Book alloc] init];
    9. book1.name = @"sanguo";
    10. book1.price = 20;
    11. TRStudent* stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan" andBook:book1];
    12. Book* book2 = [[Book alloc] init];
    13. book2.name = @"shuihu";
    14. book2.price = 18;
    15. TRStudent* stu2 = [TRStudent studentWithAge:19 andName:@"lisi" andBook:book2];
    16. Book* book3 = [[Book alloc] init];
    17. book3.name = @"xiyouji";
    18. book3.price = 28;
    19. TRStudent* stu3 = [TRStudent studentWithAge:20 andName:@"wangwu" andBook:book3];
    20. Book* book4 = [[Book alloc] init];
    21. book4.name = @"hongluomeng";
    22. book4.price = 24;
    23. TRStudent* stu4 = [TRStudent studentWithAge:21 andName:@"zhaoliu" andBook:book4];
    24. Book* book5 = [[Book alloc] init];
    25. book5.name = @"fengshenyanyi";
    26. book5.price = 22;
    27. TRStudent* stu5 = [TRStudent studentWithAge:22 andName:@"qianqi" andBook:book5];
    28. Book* book6 = [[Book alloc] init];
    29. book6.name = @"liaozhaizhiyi";
    30. book6.price = 15;
    31. TRStudent* stu6 = [TRStudent studentWithAge:23 andName:@"zhangfei" andBook:book6];
    32. Book* book7 = [[Book alloc] init];
    33. book7.name = @"sanxiawuyi";
    34. book7.price = 17;
    35. TRStudent* stu7 = [TRStudent studentWithAge:24 andName:@"guanyu" andBook:book7];
    36. Book* book8 = [[Book alloc] init];
    37. book8.name = @"yuefeizhuan";
    38. book8.price = 27;
    39. TRStudent* stu8 = [TRStudent studentWithAge:25 andName:@"zhaoyun" andBook:book8];
    40. //班级
    41. NSSet* class1403A = [NSSet setWithObjects:stu1,stu2,nil];
    42. NSSet* class1403B = [NSSet setWithObjects:stu3,stu4,nil];
    43. NSSet* class1403C = [NSSet setWithObjects:stu5,stu6,nil];
    44. NSSet* class1403D = [NSSet setWithObjects:stu7,stu8,nil];
    45. //学院
    46. NSSet* college3G = [NSSet setWithObjects:class1403A,class1403B,nil];
    47. NSSet* collegeTest = [NSSet setWithObjects:class1403C,class1403D,nil];
    48. //学校
    49. NSSet* tarena = [NSSet setWithObjects:college3G,collegeTest,nil];
    50. //遍历学校
    51. for (NSSet* college in tarena)
    52. {
    53. //遍历学院
    54. for (NSSet* class in college)
    55. {
    56. //遍历班级
    57. for (TRStudent* stu in class)
    58. {
    59. NSLog(@"name:%@, age:%d", stu.name, stu.age);
    60. }
    61. }
    62. }
    63. //遍历学校
    64. for (NSSet* college in tarena)
    65. {
    66. //遍历学院
    67. for (NSSet* class in college)
    68. {
    69. //输出年龄为18岁的学生信息
    70. [class makeObjectsPerformSelector:@selector(print:) withObject:[NSNumber numberWithInt:18]];
    71. //输出姓名为“张三”的学生信息
    72. [class makeObjectsPerformSelector:@selector(print:) withObject:@"zhangsan"];
    73. }
    74. }
    75. }
    76. return 0;
    77. }

    上述代码中,以下代码:

    1. //输出年龄为18岁的学生信息
    2. [class makeObjectsPerformSelector:@selector(print:) withObject:[NSNumber numberWithInt:18]];

    显示class集合中年龄为18岁的学生信息。通过向集合对象class发送NSSet类的makeObjectsPerformSelector:withObject:消息,使集合对象class中的每个元素(即TRStudent类的对象)均调用第一个实参@selector(print:)指定的TRStudent类中print方法,在控制台上输出满足条件(年龄为18岁)的学生的信息。条件(年龄为18岁)是通过makeObjectsPerformSelector:withObject:消息的第二个实参[NSNumber numberWithInt:18]传入给print方法的。

    上述代码中,以下代码:

    1. //输出姓名为“张三”的学生信息
    2. [class makeObjectsPerformSelector:@selector(print:) withObject:@"zhangsan"];

    显示class集合中姓名为zhangsan的学生信息。

    上述代码比步骤六(输出所有学生信息)中的遍历次数少了一次,这是因为NSSet类的makeObjectsPerformSelector:withObject:消息内本身还要遍历一次,把集合class内的所有元素逐个调用一次print方法。

    步骤八:在主程序中显示所有学生的书的名称和价格

    代码如下所示:

    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. Book* book1 = [[Book alloc] init];
    9. book1.name = @"sanguo";
    10. book1.price = 20;
    11. TRStudent* stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan" andBook:book1];
    12. Book* book2 = [[Book alloc] init];
    13. book2.name = @"shuihu";
    14. book2.price = 18;
    15. TRStudent* stu2 = [TRStudent studentWithAge:19 andName:@"lisi" andBook:book2];
    16. Book* book3 = [[Book alloc] init];
    17. book3.name = @"xiyouji";
    18. book3.price = 28;
    19. TRStudent* stu3 = [TRStudent studentWithAge:20 andName:@"wangwu" andBook:book3];
    20. Book* book4 = [[Book alloc] init];
    21. book4.name = @"hongluomeng";
    22. book4.price = 24;
    23. TRStudent* stu4 = [TRStudent studentWithAge:21 andName:@"zhaoliu" andBook:book4];
    24. Book* book5 = [[Book alloc] init];
    25. book5.name = @"fengshenyanyi";
    26. book5.price = 22;
    27. TRStudent* stu5 = [TRStudent studentWithAge:22 andName:@"qianqi" andBook:book5];
    28. Book* book6 = [[Book alloc] init];
    29. book6.name = @"liaozhaizhiyi";
    30. book6.price = 15;
    31. TRStudent* stu6 = [TRStudent studentWithAge:23 andName:@"zhangfei" andBook:book6];
    32. Book* book7 = [[Book alloc] init];
    33. book7.name = @"sanxiawuyi";
    34. book7.price = 17;
    35. TRStudent* stu7 = [TRStudent studentWithAge:24 andName:@"guanyu" andBook:book7];
    36. Book* book8 = [[Book alloc] init];
    37. book8.name = @"yuefeizhuan";
    38. book8.price = 27;
    39. TRStudent* stu8 = [TRStudent studentWithAge:25 andName:@"zhaoyun" andBook:book8];
    40. //班级
    41. NSSet* class1403A = [NSSet setWithObjects:stu1,stu2,nil];
    42. NSSet* class1403B = [NSSet setWithObjects:stu3,stu4,nil];
    43. NSSet* class1403C = [NSSet setWithObjects:stu5,stu6,nil];
    44. NSSet* class1403D = [NSSet setWithObjects:stu7,stu8,nil];
    45. //学院
    46. NSSet* college3G = [NSSet setWithObjects:class1403A,class1403B,nil];
    47. NSSet* collegeTest = [NSSet setWithObjects:class1403C,class1403D,nil];
    48. //学校
    49. NSSet* tarena = [NSSet setWithObjects:college3G,collegeTest,nil];
    50. //遍历学校
    51. for (NSSet* college in tarena)
    52. {
    53. //遍历学院
    54. for (NSSet* class in college)
    55. {
    56. //遍历班级
    57. for (TRStudent* stu in class)
    58. {
    59. NSLog(@"name:%@, age:%d", stu.name, stu.age);
    60. }
    61. }
    62. }
    63. //遍历学校
    64. for (NSSet* college in tarena)
    65. {
    66. //遍历学院
    67. for (NSSet* class in college)
    68. {
    69. //输出年龄为18岁的学生信息
    70. [class makeObjectsPerformSelector:@selector(print:) withObject:[NSNumber numberWithInt:18]];
    71. //输出姓名为“张三”的学生信息
    72. [class makeObjectsPerformSelector:@selector(print:) withObject:@"zhangsan"];
    73. }
    74. }
    75. //遍历学校
    76. for (NSSet* college in tarena)
    77. {
    78. //遍历学院
    79. for (NSSet* class in college)
    80. {
    81. //遍历班级
    82. for (TRStudent* stu in class)
    83. {
    84. NSLog(@"book name:%@, price:%d", stu.book.name, stu.book.price);
    85. }
    86. }
    87. }
    88. }
    89. return 0;
    90. }

    上述代码再一次使用了三重快速遍历,这一次与步骤六(遍历输出所有学生信息)中的三重快速遍历相比,区别是最后使用NSLog输出为书的名称和价格,不是学生的姓名和年龄。

    2.3 完整代码

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

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

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

    1. #import "Book.h"
    2. @implementation Book
    3. -(id)copyWithZone:(NSZone*)zone
    4. {
    5. Book* book = [[Book allocWithZone:zone] init];
    6. book.name = self.name;
    7. book.price = self.price;
    8. return book;
    9. }
    10. -(void)dealloc{
    11. NSLog(@"书对象销毁了 price:%d",self.price);
    12. }
    13. @end

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

    1. #import <Foundation/Foundation.h>
    2. #import "Book.h"
    3. @interface TRStudent : NSObject
    4. @property(nonatomic,assign)int age;
    5. @property(nonatomic,copy)NSString* name;
    6. @property(nonatomic,copy)Book *book;
    7. -(id)initWithAge:(int)age andName:(NSString*)name andBook:(Book*)book;
    8. +(id)studentWithAge:(int)age andName:(NSString*)name andBook:(Book*)book;
    9. -(void)print:(id)condition;
    10. @end

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

    1. #import "TRStudent.h"
    2. @implementation TRStudent
    3. -(id)initWithAge:(int)age
    4. andName:(NSString*)name
    5. andBook:(Book*)book{
    6. self = [super init];
    7. if (self) {
    8. self.age = age;
    9. self.name = name;
    10. self.book = book;
    11. }
    12. return self;
    13. }
    14. +(id)studentWithAge:(int)age
    15. andName:(NSString*)name
    16. andBook:(Book*)book{
    17. return [[TRStudent alloc]initWithAge:age andName:name andBook:book];
    18. }
    19. -(void)print:(id)condition
    20. {
    21. bool a = [condition isKindOfClass:[NSNumber class]];
    22. bool b = [condition intValue] == self.age;
    23. bool c = [condition isKindOfClass:[NSString class]];
    24. bool d = [self.name isEqualToString:condition];
    25. if ((a && b) || (c && d))
    26. NSLog(@"stu name:%@, age:%d", self.name, self.age);
    27. }
    28. @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. Book* book1 = [[Book alloc] init];
    9. book1.name = @"sanguo";
    10. book1.price = 20;
    11. TRStudent* stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan" andBook:book1];
    12. Book* book2 = [[Book alloc] init];
    13. book2.name = @"shuihu";
    14. book2.price = 18;
    15. TRStudent* stu2 = [TRStudent studentWithAge:19 andName:@"lisi" andBook:book2];
    16. Book* book3 = [[Book alloc] init];
    17. book3.name = @"xiyouji";
    18. book3.price = 28;
    19. TRStudent* stu3 = [TRStudent studentWithAge:20 andName:@"wangwu" andBook:book3];
    20. Book* book4 = [[Book alloc] init];
    21. book4.name = @"hongluomeng";
    22. book4.price = 24;
    23. TRStudent* stu4 = [TRStudent studentWithAge:21 andName:@"zhaoliu" andBook:book4];
    24. Book* book5 = [[Book alloc] init];
    25. book5.name = @"fengshenyanyi";
    26. book5.price = 22;
    27. TRStudent* stu5 = [TRStudent studentWithAge:22 andName:@"qianqi" andBook:book5];
    28. Book* book6 = [[Book alloc] init];
    29. book6.name = @"liaozhaizhiyi";
    30. book6.price = 15;
    31. TRStudent* stu6 = [TRStudent studentWithAge:23 andName:@"zhangfei" andBook:book6];
    32. Book* book7 = [[Book alloc] init];
    33. book7.name = @"sanxiawuyi";
    34. book7.price = 17;
    35. TRStudent* stu7 = [TRStudent studentWithAge:24 andName:@"guanyu" andBook:book7];
    36. Book* book8 = [[Book alloc] init];
    37. book8.name = @"yuefeizhuan";
    38. book8.price = 27;
    39. TRStudent* stu8 = [TRStudent studentWithAge:25 andName:@"zhaoyun" andBook:book8];
    40. //班级
    41. NSSet* class1403A = [NSSet setWithObjects:stu1,stu2,nil];
    42. NSSet* class1403B = [NSSet setWithObjects:stu3,stu4,nil];
    43. NSSet* class1403C = [NSSet setWithObjects:stu5,stu6,nil];
    44. NSSet* class1403D = [NSSet setWithObjects:stu7,stu8,nil];
    45. //学院
    46. NSSet* college3G = [NSSet setWithObjects:class1403A,class1403B,nil];
    47. NSSet* collegeTest = [NSSet setWithObjects:class1403C,class1403D,nil];
    48. //学校
    49. NSSet* tarena = [NSSet setWithObjects:college3G,collegeTest,nil];
    50. //遍历学校
    51. for (NSSet* college in tarena)
    52. {
    53. //遍历学院
    54. for (NSSet* class in college)
    55. {
    56. //遍历班级
    57. for (TRStudent* stu in class)
    58. {
    59. NSLog(@"stu name:%@, age:%d", stu.name, stu.age);
    60. }
    61. }
    62. }
    63. //遍历学校
    64. for (NSSet* college in tarena)
    65. {
    66. //遍历学院
    67. for (NSSet* class in college)
    68. {
    69. //输出年龄为18岁的学生信息
    70. [class makeObjectsPerformSelector:@selector(print:) withObject:[NSNumber numberWithInt:18]];
    71. //输出姓名为“张三”的学生信息
    72. [class makeObjectsPerformSelector:@selector(print:) withObject:@"zhangsan"];
    73. }
    74. }
    75. //遍历学校
    76. for (NSSet* college in tarena)
    77. {
    78. //遍历学院
    79. for (NSSet* class in college)
    80. {
    81. //遍历班级
    82. for (TRStudent* stu in class)
    83. {
    84. NSLog(@"book name:%@, price:%d", stu.book.name, stu.book.price);
    85. }
    86. }
    87. }
    88. }
    89. return 0;
    90. }
  • 相关阅读:
    Android之TabHost实现Tab切换
    银联支付SDK集成
    iOS 支付 [支付宝、银联、微信]
    MySQL数据库数据类型以及INT(M)的含义
    cherrypy
    使用PyMySQL操作mysql数据库
    面向新手的Web服务器搭建(一)——IIS的搭建
    SQLite3中自增主键相关知识总结,清零的方法、INTEGER PRIMARY KEY AUTOINCREMENT和rowid的使用
    FMDB-FMDatabaseQueue
    SQLite 数据类型
  • 原文地址:https://www.cnblogs.com/52190112cn/p/5049289.html