NSArray(二) 、 NSMutableArray 、 NSSet 、 NSMutableSet
1 创建五个学生对象,放入数组并遍历
1.1 问题
创建一个自定义类TRStudent,为该类生成五个对象。把这五个对象存入一个数组当中,然后遍历数组。
1.2 步骤
实现此案例需要按照如下步骤进行。
步骤一:定义类TRStudent
首先,在Day03工程中新添加TRStudent.h文件,用于定义新的类TRStudent。
代码如下所示:
- #import <Foundation/Foundation.h>
- @interface TRStudent : NSObject
- @property(nonatomic,assign)int age;
- @property(nonatomic,copy)NSString* name;
- @end
在上述代码中,以下代码:
- @property(nonatomic,assign)int age;
- @property(nonatomic,copy)NSString* name;
在TRStudent类中定义了两个属性,一个是整型变量age,用于存储学生的年龄;另一个是NSString类的对象name,用于存储学生的姓名。
然后,在类TRStudent的实现部分,即在TRStudent.m文件中,重写description方法的实现,该方法用于在NSLog中用%@输出TRStudent类的对象值。
代码如下所示:
- #import "TRStudent.h"
- @implementation TRStudent
- -(NSString *)description{
- return [NSString stringWithFormat:@"age:%d",self.age];
- }
- @end
上述代码中,以下代码:
- -(NSString *)description{
- return [NSString stringWithFormat:@"student age:%d name:%@",self.age,self.name];
- }
是重写description方法的实现,该方法用于在NSLog中用%@输出TRStudent类的对象值。
步骤二:在主程序中定义五个学生对象
代码如下所示:
- #import <Foundation/Foundation.h>
- #import "TRStudent.h"
- int main(int argc, const char * argv[])
- {
- @autoreleasepool {
- // insert code here...
- TRStudent* stu = [[TRStudent alloc]init];
- stu.age = 18;
- stu.name = @"zhangsan";
- TRStudent* stu2 = [[TRStudent alloc]init];
- stu2.age = 20;
- stu2.name = @"lisi";
- TRStudent* stu3 = [[TRStudent alloc]init];
- stu3.age = 30;
- stu3.name = @"wangwu";
- TRStudent* stu4 = [[TRStudent alloc]init];
- stu4.age = 40;
- stu4.name = @"zhaoliu";
- TRStudent* stu5 = [[TRStudent alloc]init];
- stu5.age = 35;
- stu5.name = @"qianqi";
- }
- return 0;
- }
步骤三:使用五个学生对象生成一个可变数组
代码如下所示:
- #import <Foundation/Foundation.h>
- #import "TRStudent.h"
- int main(int argc, const char * argv[])
- {
- @autoreleasepool {
- // insert code here...
- TRStudent* stu = [[TRStudent alloc]init];
- stu.age = 18;
- stu.name = @"zhangsan";
- TRStudent* stu2 = [[TRStudent alloc]init];
- stu2.age = 20;
- stu2.name = @"lisi";
- TRStudent* stu3 = [[TRStudent alloc]init];
- stu3.age = 30;
- stu3.name = @"wangwu";
- TRStudent* stu4 = [[TRStudent alloc]init];
- stu4.age = 40;
- stu4.name = @"zhaoliu";
- TRStudent* stu5 = [[TRStudent alloc]init];
- stu5.age = 35;
- stu5.name = @"qianqi";
- NSMutableArray* students = [NSMutableArray arrayWithObjects:stu,stu2,stu3,stu4,stu5, nil];
- }
- return 0;
- }
上述代码中,以下代码:
- NSMutableArray* students = [NSMutableArray arrayWithObjects:stu,stu2,stu3,stu4,stu5, nil];
生成一个可变数组类NSMutableArray的对象students。并使用NSMutableArray类的方法arrayWithObjects将students初始化为上述五个学生对象。值得注意的是实参的最后是nil,它的作用是标志后面没有要初始化的对象了。
步骤四:对五个学生对象进行遍历
代码如下所示:
- #import <Foundation/Foundation.h>
- #import "TRStudent.h"
- int main(int argc, const char * argv[])
- {
- @autoreleasepool {
- // insert code here...
- TRStudent* stu = [[TRStudent alloc]init];
- stu.age = 18;
- stu.name = @"zhangsan";
- TRStudent* stu2 = [[TRStudent alloc]init];
- stu2.age = 20;
- stu2.name = @"lisi";
- TRStudent* stu3 = [[TRStudent alloc]init];
- stu3.age = 30;
- stu3.name = @"wangwu";
- TRStudent* stu4 = [[TRStudent alloc]init];
- stu4.age = 40;
- stu4.name = @"zhaoliu";
- TRStudent* stu5 = [[TRStudent alloc]init];
- stu5.age = 35;
- stu5.name = @"qianqi";
- NSMutableArray* students = [NSMutableArray arrayWithObjects:stu,stu2,stu3,stu4,stu5, nil];
- NSLog(@"遍历学生内容..........");
- for (int i = 0; i<[students count]; i++) {
- TRStudent* stu = [students objectAtIndex:i];
- NSLog(@"stu age:%d name:%@",stu.age,stu.name);
- }
- }
- return 0;
- }
上述代码中,以下代码:
- for (int i = 0; i<[students count]; i++) {
- TRStudent* stu = [students objectAtIndex:i];
- NSLog(@"stu age:%d name:%@",stu.age,stu.name);
- }
是设置一个循环来遍历数组。NSMutableArray类的方法count返回对象students中的数组元素个数,在这里用于限定循环的次数。NSMutableArray类的方法objectAtIndex:返回指定位置的数组元素值,实参i用于指定要返回哪个数组元素。最后,使用NSLog在控制台上输出TRStudent类对象的两个属性值。
1.3 完整代码
本案例中,类TRStudent声明,即TRStudent.h文件,完整代码如下所示:
- #import <Foundation/Foundation.h>
- @interface TRStudent : NSObject
- @property(nonatomic,assign)int age;
- @property(nonatomic,copy)NSString* name;
- @end
类TRStudent实现,即TRStudent.m文件,完整代码如下所示:
- #import "TRStudent.h"
- @implementation TRStudent
- -(NSString *)description{
- return [NSString stringWithFormat:@"age:%d",self.age];
- }
- @end
主程序,即main.m,完整代码如下所示:
- #import <Foundation/Foundation.h>
- #import "TRStudent.h"
- int main(int argc, const char * argv[])
- {
- @autoreleasepool {
- // insert code here...
- TRStudent* stu = [[TRStudent alloc]init];
- stu.age = 18;
- stu.name = @"zhangsan";
- TRStudent* stu2 = [[TRStudent alloc]init];
- stu2.age = 20;
- stu2.name = @"lisi";
- TRStudent* stu3 = [[TRStudent alloc]init];
- stu3.age = 30;
- stu3.name = @"wangwu";
- TRStudent* stu4 = [[TRStudent alloc]init];
- stu4.age = 40;
- stu4.name = @"zhaoliu";
- TRStudent* stu5 = [[TRStudent alloc]init];
- stu5.age = 35;
- stu5.name = @"qianqi";
- NSMutableArray* students = [NSMutableArray arrayWithObjects:stu,stu2,stu3,stu4,stu5, nil];
- NSLog(@"遍历学生内容..........");
- for (int i = 0; i<[students count]; i++) {
- TRStudent* stu = [students objectAtIndex:i];
- NSLog(@"stu age:%d name:%@",stu.age,stu.name);
- }
- }
- return 0;
- }
2 重构学生与学校的练习
2.1 问题
本案例要求用集合解决下述问题。问题是:有一个学校,该学校有两个学院,每个学院中又有两个班级,而在每个班级中有两名学生。
现在作如下要求:
1)显示所有学生的信息。
2)只显示姓名为“zhangsan”的学生的信息。
3)只显示年龄为18岁的学生的信息。
4)如果每个学生有本书,显示所有学生的书的名称和价格。
2.2 步骤
实现此案例需要按照如下步骤进行。
步骤一:定义类Book
首先,在Day03-2工程中新添加Book.h文件,用于定义新的类Book。
代码如下所示:
- #import <Foundation/Foundation.h>
- @interface Book : NSObject<NSCopying>
- @property(nonatomic, copy)NSString *name;
- @property(nonatomic,assign)int price;
- @end
在上述代码中,以下代码:
- @interface Book : NSObject<NSCopying>
定义了类Book,该类采用了NSCopying协议。
在上述代码中,以下代码:
- @property(nonatomic, copy)NSString *name;
- @property(nonatomic,assign)int price;
在Book类中定义了两个属性,一个是NSString类的对象name,用于存储书的名字;另一个是整型变量price,用于存储书的价格。
然后,在类Book的实现部分,即在Book.m文件中,添加两个方法的实现,一个是copyWithZone方法,该方法是在NSCopying协议中声明的方法,用于深拷贝;另一个是dealloc方法,由于使用ARC,该方法在本类中实际上没有任何实际意义,只是在类的对象销毁时,在控制台上输出一个提示。
代码如下所示:
- #import "Book.h"
- @implementation Book
- -(id)copyWithZone:(NSZone*)zone
- {
- Book* book = [[Book allocWithZone:zone] init];
- book.name = self.name;
- book.price = self.price;
- return book;
- }
- -(void)dealloc{
- NSLog(@"书对象销毁了 price:%d",self.price);
- }
- @end
上述代码中,copyWithZone方法不能在类外直接被调用,它是在向一个对象发送copy消息时,由copy消息调用。在该方法中,以下代码:
- Book* book = [[Book allocWithZone:zone] init];
- book.name = self.name;
- book.price = self.price;
生成一个本类对象的副本。需要注意的是分配空间使用的是allocWithZone方法。
上述代码中,dealloc方法也不能在类外直接被调用,它是在一个对象被release并且对象的引用计数为0时,由内存管理程序调用的方法。
步骤二:定义类TRStudent
首先,在Day03-2工程中新添加TRStudent.h文件,用于定义新的类TRStudent。
代码如下所示:
- #import <Foundation/Foundation.h>
- #import "Book.h"
- @interface TRStudent : NSObject
- @property(nonatomic,assign)int age;
- @property(nonatomic,copy)NSString* name;
- @property(nonatomic,copy)Book *book;
- -(id)initWithAge:(int)age andName:(NSString*)name andBook:(Book*)book;
- +(id)studentWithAge:(int)age andName:(NSString*)name andBook:(Book*)book;
- -(void)print:(id)condition;
- @end
在上述代码中,定义了类Student,在类中有三个带参属性。
一个属性是整型变量age,如下代码所示:
- @property(nonatomic,assign) int age;
用于存储学生的年龄。它有两个参数,一个是nonatomic,它代表对属性赋值的时候不加锁,即在多线程环境下访问时可能会出现数据错误,如果需要在多线程环境下运行,为保证数据不会出现错误,可使用atomic参数,它会在对属性赋值的时候加锁。另一个参数是assign,对于C语言的基本数据类型,只能选取这个参数。
另一个属性是name,如下代码所示:
- @property(nonatomic,copy)NSString* name;
用于存储学生的姓名。它有两个参数,一个是nonatomic,另一个参数是copy,该参数一般用于NSObject类及其子类的对象,这些对象在赋值时实现深拷贝,即属性name指向的对象是赋值给它的对象的副本。
最后一个属性是book,如下代码所示:
- @property(nonatomic,copy)Book *book;
用于存储学生正在学习的书。值得注意的是,Book类采纳NSCopying协议,是因为此处使用了copy这个属性参数。
上述代码中,以下代码:
- -(id)initWithAge:(int)age andName:(NSString*)name andBook:(Book*)book;
- +(id)studentWithAge:(int)age andName:(NSString*)name andBook:(Book*)book;
声明了TRStudent类的带参初始化方法和带参工厂方法。
上述代码中,以下代码:
- -(void)print:(id)condition;
声明了一个print方法,该方法用于根据形参condition的不同,打印不同的TRStudent类对象的属性值。
然后,在类Student的实现部分,即在Student.m文件中,添加带参初始化方法和工厂初始化方法以及print方法的实现。
代码如下所示:
- #import "TRStudent.h"
- @implementation TRStudent
- -(id)initWithAge:(int)age
- andName:(NSString*)name
- andBook:(Book*)book{
- self = [super init];
- if (self) {
- self.age = age;
- self.name = name;
- self.book = book;
- }
- return self;
- }
- +(id)studentWithAge:(int)age
- andName:(NSString*)name
- andBook:(Book*)book{
- return [[TRStudent alloc]initWithAge:age andName:name andBook:book];
- }
- -(void)print:(id)condition
- {
- bool a = [condition isKindOfClass:[NSNumber class]];
- bool b = [condition intValue] == self.age;
- bool c = [condition isKindOfClass:[NSString class]];
- bool d = [self.name isEqualToString:condition];
- if ((a && b) || (c && d))
- NSLog(@"stu name:%@, age:%d", self.name, self.age);
- }
- @end
上述代码中,以下代码:
- bool a = [condition isKindOfClass:[NSNumber class]];
- bool b = [condition intValue] == self.age;
定义了两个bool类型的变量。
变量a被赋值为形参condition是否是NSNumber类对象的判断结果,其中方法isKindOfClass的作用是判断对象condition是否是NSNumber类的对象。方法isKindOfClass的形参为Class类型的值,该类型的值通过工厂方法class获得。
变量b被赋值为形参condition的值是否与当前对象age属性值相等的判断结果。通过向形参condition发送intValue消息,如果condition的值为数字字符串,则将其转换成整型数据。
上述代码中,以下代码:
- bool c = [condition isKindOfClass:[NSString class]];
- bool d = [self.name isEqualToString:condition];
定义了两个bool类型的变量。
变量c被赋值为形参condition是否是NSString类对象的判断结果。
变量d被赋值为当前对象name属性值是否与形参condition的值相等的判断结果。方法isEqualToString是NSString类的方法,用于判断两个字符串是否相等。
上述代码中,以下代码:
- if ((a && b) || (c && d))
- NSLog(@"stu name:%@, age:%d", self.name, self.age);
如果条件(a && b)为真则表示形参condition为NSNumber类的对象并且将其拆箱后的值与当前对象age属性值相等。
如果条件(c && d)为真则表示形参condition为NSString类的对象并且与当前对象name属性值是同一字符串。
步骤三:在主程序中创建八个学生对象
代码如下所示:
- #import <Foundation/Foundation.h>
- #import "TRStudent.h"
- int main(int argc, const char * argv[])
- {
- @autoreleasepool {
- // insert code here...
- //创建学生对象
- Book* book1 = [[Book alloc] init];
- book1.name = @"sanguo";
- book1.price = 20;
- TRStudent* stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan" andBook:book1];
- Book* book2 = [[Book alloc] init];
- book2.name = @"shuihu";
- book2.price = 18;
- TRStudent* stu2 = [TRStudent studentWithAge:19 andName:@"lisi" andBook:book2];
- Book* book3 = [[Book alloc] init];
- book3.name = @"xiyouji";
- book3.price = 28;
- TRStudent* stu3 = [TRStudent studentWithAge:20 andName:@"wangwu" andBook:book3];
- Book* book4 = [[Book alloc] init];
- book4.name = @"hongluomeng";
- book4.price = 24;
- TRStudent* stu4 = [TRStudent studentWithAge:21 andName:@"zhaoliu" andBook:book4];
- Book* book5 = [[Book alloc] init];
- book5.name = @"fengshenyanyi";
- book5.price = 22;
- TRStudent* stu5 = [TRStudent studentWithAge:22 andName:@"qianqi" andBook:book5];
- Book* book6 = [[Book alloc] init];
- book6.name = @"liaozhaizhiyi";
- book6.price = 15;
- TRStudent* stu6 = [TRStudent studentWithAge:23 andName:@"zhangfei" andBook:book6];
- Book* book7 = [[Book alloc] init];
- book7.name = @"sanxiawuyi";
- book7.price = 17;
- TRStudent* stu7 = [TRStudent studentWithAge:24 andName:@"guanyu" andBook:book7];
- Book* book8 = [[Book alloc] init];
- book8.name = @"yuefeizhuan";
- book8.price = 27;
- TRStudent* stu8 = [TRStudent studentWithAge:25 andName:@"zhaoyun" andBook:book8];
- }
- return 0;
- }
上述代码中,以下代码:
- //创建学生对象
- Book* book1 = [[Book alloc] init];
- book1.name = @"sanguo";
- book1.price = 20;
- TRStudent* stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan" andBook:book1];
首先创建了一个Book类的对象book1,然后使用工厂方法studentWithAge:andName:andBook:创建TRStudent类的对象stu1。
步骤四:在主程序中创建班级集合
代码如下所示:
- #import <Foundation/Foundation.h>
- #import "TRStudent.h"
- int main(int argc, const char * argv[])
- {
- @autoreleasepool {
- // insert code here...
- //创建学生对象
- Book* book1 = [[Book alloc] init];
- book1.name = @"sanguo";
- book1.price = 20;
- TRStudent* stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan" andBook:book1];
- Book* book2 = [[Book alloc] init];
- book2.name = @"shuihu";
- book2.price = 18;
- TRStudent* stu2 = [TRStudent studentWithAge:19 andName:@"lisi" andBook:book2];
- Book* book3 = [[Book alloc] init];
- book3.name = @"xiyouji";
- book3.price = 28;
- TRStudent* stu3 = [TRStudent studentWithAge:20 andName:@"wangwu" andBook:book3];
- Book* book4 = [[Book alloc] init];
- book4.name = @"hongluomeng";
- book4.price = 24;
- TRStudent* stu4 = [TRStudent studentWithAge:21 andName:@"zhaoliu" andBook:book4];
- Book* book5 = [[Book alloc] init];
- book5.name = @"fengshenyanyi";
- book5.price = 22;
- TRStudent* stu5 = [TRStudent studentWithAge:22 andName:@"qianqi" andBook:book5];
- Book* book6 = [[Book alloc] init];
- book6.name = @"liaozhaizhiyi";
- book6.price = 15;
- TRStudent* stu6 = [TRStudent studentWithAge:23 andName:@"zhangfei" andBook:book6];
- Book* book7 = [[Book alloc] init];
- book7.name = @"sanxiawuyi";
- book7.price = 17;
- TRStudent* stu7 = [TRStudent studentWithAge:24 andName:@"guanyu" andBook:book7];
- Book* book8 = [[Book alloc] init];
- book8.name = @"yuefeizhuan";
- book8.price = 27;
- TRStudent* stu8 = [TRStudent studentWithAge:25 andName:@"zhaoyun" andBook:book8];
- //班级
- NSSet* class1403A = [NSSet setWithObjects:stu1,stu2,nil];
- NSSet* class1403B = [NSSet setWithObjects:stu3,stu4,nil];
- NSSet* class1403C = [NSSet setWithObjects:stu5,stu6,nil];
- NSSet* class1403D = [NSSet setWithObjects:stu7,stu8,nil];
- }
- return 0;
- }
上述代码中,以下代码:
- //班级
- NSSet* class1403A = [NSSet setWithObjects:stu1,stu2,nil];
- NSSet* class1403B = [NSSet setWithObjects:stu3,stu4,nil];
- NSSet* class1403C = [NSSet setWithObjects:stu5,stu6,nil];
- NSSet* class1403D = [NSSet setWithObjects:stu7,stu8,nil];
创建了四个集合对象,每个集合对象为一个班级,班级中有两个学生作为集合元素。其中使用工厂方法setWithObjects创建集合对象。值得注意的是,在形参的最后是nil,它代表放入集合中的元素结束。
步骤五:在主程序中创建学院和学校
代码如下所示:
- #import <Foundation/Foundation.h>
- #import "TRStudent.h"
- int main(int argc, const char * argv[])
- {
- @autoreleasepool {
- // insert code here...
- //创建学生对象
- Book* book1 = [[Book alloc] init];
- book1.name = @"sanguo";
- book1.price = 20;
- TRStudent* stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan" andBook:book1];
- Book* book2 = [[Book alloc] init];
- book2.name = @"shuihu";
- book2.price = 18;
- TRStudent* stu2 = [TRStudent studentWithAge:19 andName:@"lisi" andBook:book2];
- Book* book3 = [[Book alloc] init];
- book3.name = @"xiyouji";
- book3.price = 28;
- TRStudent* stu3 = [TRStudent studentWithAge:20 andName:@"wangwu" andBook:book3];
- Book* book4 = [[Book alloc] init];
- book4.name = @"hongluomeng";
- book4.price = 24;
- TRStudent* stu4 = [TRStudent studentWithAge:21 andName:@"zhaoliu" andBook:book4];
- Book* book5 = [[Book alloc] init];
- book5.name = @"fengshenyanyi";
- book5.price = 22;
- TRStudent* stu5 = [TRStudent studentWithAge:22 andName:@"qianqi" andBook:book5];
- Book* book6 = [[Book alloc] init];
- book6.name = @"liaozhaizhiyi";
- book6.price = 15;
- TRStudent* stu6 = [TRStudent studentWithAge:23 andName:@"zhangfei" andBook:book6];
- Book* book7 = [[Book alloc] init];
- book7.name = @"sanxiawuyi";
- book7.price = 17;
- TRStudent* stu7 = [TRStudent studentWithAge:24 andName:@"guanyu" andBook:book7];
- Book* book8 = [[Book alloc] init];
- book8.name = @"yuefeizhuan";
- book8.price = 27;
- TRStudent* stu8 = [TRStudent studentWithAge:25 andName:@"zhaoyun" andBook:book8];
- //班级
- NSSet* class1403A = [NSSet setWithObjects:stu1,stu2,nil];
- NSSet* class1403B = [NSSet setWithObjects:stu3,stu4,nil];
- NSSet* class1403C = [NSSet setWithObjects:stu5,stu6,nil];
- NSSet* class1403D = [NSSet setWithObjects:stu7,stu8,nil];
- //学院
- NSSet* college3G = [NSSet setWithObjects:class1403A,class1403B,nil];
- NSSet* collegeTest = [NSSet setWithObjects:class1403C,class1403D,nil];
- //学校
- NSSet* tarena = [NSSet setWithObjects:college3G,collegeTest,nil];
- }
- return 0;
- }
上述代码中,以下代码:
- //学院
- NSSet* college3G = [NSSet setWithObjects:class1403A,class1403B,nil];
- NSSet* collegeTest = [NSSet setWithObjects:class1403C,class1403D,nil];
- //学校
- NSSet* tarena = [NSSet setWithObjects:college3G,collegeTest,nil];
创建了两个学院集合,每个学院集合中有两个班级集合作为集合元素。还创建了一个学校集合,其中包含上述两个学院集合作为集合元素。
步骤六:在主程序中遍历输出所有学生信息
代码如下所示:
- #import <Foundation/Foundation.h>
- #import "TRStudent.h"
- int main(int argc, const char * argv[])
- {
- @autoreleasepool {
- // insert code here...
- //创建学生对象
- Book* book1 = [[Book alloc] init];
- book1.name = @"sanguo";
- book1.price = 20;
- TRStudent* stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan" andBook:book1];
- Book* book2 = [[Book alloc] init];
- book2.name = @"shuihu";
- book2.price = 18;
- TRStudent* stu2 = [TRStudent studentWithAge:19 andName:@"lisi" andBook:book2];
- Book* book3 = [[Book alloc] init];
- book3.name = @"xiyouji";
- book3.price = 28;
- TRStudent* stu3 = [TRStudent studentWithAge:20 andName:@"wangwu" andBook:book3];
- Book* book4 = [[Book alloc] init];
- book4.name = @"hongluomeng";
- book4.price = 24;
- TRStudent* stu4 = [TRStudent studentWithAge:21 andName:@"zhaoliu" andBook:book4];
- Book* book5 = [[Book alloc] init];
- book5.name = @"fengshenyanyi";
- book5.price = 22;
- TRStudent* stu5 = [TRStudent studentWithAge:22 andName:@"qianqi" andBook:book5];
- Book* book6 = [[Book alloc] init];
- book6.name = @"liaozhaizhiyi";
- book6.price = 15;
- TRStudent* stu6 = [TRStudent studentWithAge:23 andName:@"zhangfei" andBook:book6];
- Book* book7 = [[Book alloc] init];
- book7.name = @"sanxiawuyi";
- book7.price = 17;
- TRStudent* stu7 = [TRStudent studentWithAge:24 andName:@"guanyu" andBook:book7];
- Book* book8 = [[Book alloc] init];
- book8.name = @"yuefeizhuan";
- book8.price = 27;
- TRStudent* stu8 = [TRStudent studentWithAge:25 andName:@"zhaoyun" andBook:book8];
- //班级
- NSSet* class1403A = [NSSet setWithObjects:stu1,stu2,nil];
- NSSet* class1403B = [NSSet setWithObjects:stu3,stu4,nil];
- NSSet* class1403C = [NSSet setWithObjects:stu5,stu6,nil];
- NSSet* class1403D = [NSSet setWithObjects:stu7,stu8,nil];
- //学院
- NSSet* college3G = [NSSet setWithObjects:class1403A,class1403B,nil];
- NSSet* collegeTest = [NSSet setWithObjects:class1403C,class1403D,nil];
- //学校
- NSSet* tarena = [NSSet setWithObjects:college3G,collegeTest,nil];
- //遍历学校
- for (NSSet* college in tarena)
- {
- //遍历学院
- for (NSSet* class in college)
- {
- //遍历班级
- for (TRStudent* stu in class)
- {
- NSLog(@"stu name:%@, age:%d", stu.name, stu.age);
- }
- }
- }
- }
- return 0;
- }
上述代码中,以下代码:
- //遍历学校
- for (NSSet* college in tarena)
- {
- //遍历学院
- for (NSSet* class in college)
- {
- //遍历班级
- for (TRStudent* stu in class)
- {
- NSLog(@"name:%@, age:%d", stu.name, stu.age);
- }
- }
- }
通过三重快速遍历方法遍历所有学生的信息。以下代码:
- //遍历学校
- for (NSSet* college in tarena)
是遍历学校tarena。每次从集合tarena中取出一个元素,放入college中,因为学校集合tarena内的元素为两个学院集合,所以college的数据类型为NSSet*。
以下代码:
- //遍历学院
- for (NSSet* class in college)
是遍历学院college。每次从集合college中取出一个元素,放入class中,因为学院集合college内的元素为两个班级集合,所以class的数据类型为NSSet*。
以下代码:
- //遍历班级
- for (TRStudent* stu in class)
是遍历班级class。因为班级集合class中是两个学生类TRStudent的对象,所以stu的数据类型为TRStudent*。
步骤七:在主程序中遍历显示指定条件的学生信息
代码如下所示:
- #import <Foundation/Foundation.h>
- #import "TRStudent.h"
- int main(int argc, const char * argv[])
- {
- @autoreleasepool {
- // insert code here...
- //创建学生对象
- Book* book1 = [[Book alloc] init];
- book1.name = @"sanguo";
- book1.price = 20;
- TRStudent* stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan" andBook:book1];
- Book* book2 = [[Book alloc] init];
- book2.name = @"shuihu";
- book2.price = 18;
- TRStudent* stu2 = [TRStudent studentWithAge:19 andName:@"lisi" andBook:book2];
- Book* book3 = [[Book alloc] init];
- book3.name = @"xiyouji";
- book3.price = 28;
- TRStudent* stu3 = [TRStudent studentWithAge:20 andName:@"wangwu" andBook:book3];
- Book* book4 = [[Book alloc] init];
- book4.name = @"hongluomeng";
- book4.price = 24;
- TRStudent* stu4 = [TRStudent studentWithAge:21 andName:@"zhaoliu" andBook:book4];
- Book* book5 = [[Book alloc] init];
- book5.name = @"fengshenyanyi";
- book5.price = 22;
- TRStudent* stu5 = [TRStudent studentWithAge:22 andName:@"qianqi" andBook:book5];
- Book* book6 = [[Book alloc] init];
- book6.name = @"liaozhaizhiyi";
- book6.price = 15;
- TRStudent* stu6 = [TRStudent studentWithAge:23 andName:@"zhangfei" andBook:book6];
- Book* book7 = [[Book alloc] init];
- book7.name = @"sanxiawuyi";
- book7.price = 17;
- TRStudent* stu7 = [TRStudent studentWithAge:24 andName:@"guanyu" andBook:book7];
- Book* book8 = [[Book alloc] init];
- book8.name = @"yuefeizhuan";
- book8.price = 27;
- TRStudent* stu8 = [TRStudent studentWithAge:25 andName:@"zhaoyun" andBook:book8];
- //班级
- NSSet* class1403A = [NSSet setWithObjects:stu1,stu2,nil];
- NSSet* class1403B = [NSSet setWithObjects:stu3,stu4,nil];
- NSSet* class1403C = [NSSet setWithObjects:stu5,stu6,nil];
- NSSet* class1403D = [NSSet setWithObjects:stu7,stu8,nil];
- //学院
- NSSet* college3G = [NSSet setWithObjects:class1403A,class1403B,nil];
- NSSet* collegeTest = [NSSet setWithObjects:class1403C,class1403D,nil];
- //学校
- NSSet* tarena = [NSSet setWithObjects:college3G,collegeTest,nil];
- //遍历学校
- for (NSSet* college in tarena)
- {
- //遍历学院
- for (NSSet* class in college)
- {
- //遍历班级
- for (TRStudent* stu in class)
- {
- NSLog(@"name:%@, age:%d", stu.name, stu.age);
- }
- }
- }
- //遍历学校
- for (NSSet* college in tarena)
- {
- //遍历学院
- for (NSSet* class in college)
- {
- //输出年龄为18岁的学生信息
- [class makeObjectsPerformSelector:@selector(print:) withObject:[NSNumber numberWithInt:18]];
- //输出姓名为“张三”的学生信息
- [class makeObjectsPerformSelector:@selector(print:) withObject:@"zhangsan"];
- }
- }
- }
- return 0;
- }
上述代码中,以下代码:
- //输出年龄为18岁的学生信息
- [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方法的。
上述代码中,以下代码:
- //输出姓名为“张三”的学生信息
- [class makeObjectsPerformSelector:@selector(print:) withObject:@"zhangsan"];
显示class集合中姓名为zhangsan的学生信息。
上述代码比步骤六(输出所有学生信息)中的遍历次数少了一次,这是因为NSSet类的makeObjectsPerformSelector:withObject:消息内本身还要遍历一次,把集合class内的所有元素逐个调用一次print方法。
步骤八:在主程序中显示所有学生的书的名称和价格
代码如下所示:
- #import <Foundation/Foundation.h>
- #import "TRStudent.h"
- int main(int argc, const char * argv[])
- {
- @autoreleasepool {
- // insert code here...
- //创建学生对象
- Book* book1 = [[Book alloc] init];
- book1.name = @"sanguo";
- book1.price = 20;
- TRStudent* stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan" andBook:book1];
- Book* book2 = [[Book alloc] init];
- book2.name = @"shuihu";
- book2.price = 18;
- TRStudent* stu2 = [TRStudent studentWithAge:19 andName:@"lisi" andBook:book2];
- Book* book3 = [[Book alloc] init];
- book3.name = @"xiyouji";
- book3.price = 28;
- TRStudent* stu3 = [TRStudent studentWithAge:20 andName:@"wangwu" andBook:book3];
- Book* book4 = [[Book alloc] init];
- book4.name = @"hongluomeng";
- book4.price = 24;
- TRStudent* stu4 = [TRStudent studentWithAge:21 andName:@"zhaoliu" andBook:book4];
- Book* book5 = [[Book alloc] init];
- book5.name = @"fengshenyanyi";
- book5.price = 22;
- TRStudent* stu5 = [TRStudent studentWithAge:22 andName:@"qianqi" andBook:book5];
- Book* book6 = [[Book alloc] init];
- book6.name = @"liaozhaizhiyi";
- book6.price = 15;
- TRStudent* stu6 = [TRStudent studentWithAge:23 andName:@"zhangfei" andBook:book6];
- Book* book7 = [[Book alloc] init];
- book7.name = @"sanxiawuyi";
- book7.price = 17;
- TRStudent* stu7 = [TRStudent studentWithAge:24 andName:@"guanyu" andBook:book7];
- Book* book8 = [[Book alloc] init];
- book8.name = @"yuefeizhuan";
- book8.price = 27;
- TRStudent* stu8 = [TRStudent studentWithAge:25 andName:@"zhaoyun" andBook:book8];
- //班级
- NSSet* class1403A = [NSSet setWithObjects:stu1,stu2,nil];
- NSSet* class1403B = [NSSet setWithObjects:stu3,stu4,nil];
- NSSet* class1403C = [NSSet setWithObjects:stu5,stu6,nil];
- NSSet* class1403D = [NSSet setWithObjects:stu7,stu8,nil];
- //学院
- NSSet* college3G = [NSSet setWithObjects:class1403A,class1403B,nil];
- NSSet* collegeTest = [NSSet setWithObjects:class1403C,class1403D,nil];
- //学校
- NSSet* tarena = [NSSet setWithObjects:college3G,collegeTest,nil];
- //遍历学校
- for (NSSet* college in tarena)
- {
- //遍历学院
- for (NSSet* class in college)
- {
- //遍历班级
- for (TRStudent* stu in class)
- {
- NSLog(@"name:%@, age:%d", stu.name, stu.age);
- }
- }
- }
- //遍历学校
- for (NSSet* college in tarena)
- {
- //遍历学院
- for (NSSet* class in college)
- {
- //输出年龄为18岁的学生信息
- [class makeObjectsPerformSelector:@selector(print:) withObject:[NSNumber numberWithInt:18]];
- //输出姓名为“张三”的学生信息
- [class makeObjectsPerformSelector:@selector(print:) withObject:@"zhangsan"];
- }
- }
- //遍历学校
- for (NSSet* college in tarena)
- {
- //遍历学院
- for (NSSet* class in college)
- {
- //遍历班级
- for (TRStudent* stu in class)
- {
- NSLog(@"book name:%@, price:%d", stu.book.name, stu.book.price);
- }
- }
- }
- }
- return 0;
- }
上述代码再一次使用了三重快速遍历,这一次与步骤六(遍历输出所有学生信息)中的三重快速遍历相比,区别是最后使用NSLog输出为书的名称和价格,不是学生的姓名和年龄。
2.3 完整代码
本案例中,类Book声明,即Book.h文件,完整代码如下所示:
- #import <Foundation/Foundation.h>
- @interface Book : NSObject<NSCopying>
- @property(nonatomic, copy)NSString *name;
- @property(nonatomic,assign)int price;
- @end
类Book实现,即Book.m文件,完整代码如下所示:
- #import "Book.h"
- @implementation Book
- -(id)copyWithZone:(NSZone*)zone
- {
- Book* book = [[Book allocWithZone:zone] init];
- book.name = self.name;
- book.price = self.price;
- return book;
- }
- -(void)dealloc{
- NSLog(@"书对象销毁了 price:%d",self.price);
- }
- @end
本案例中,类TRStudent声明,即TRStudent.h文件,完整代码如下所示:
- #import <Foundation/Foundation.h>
- #import "Book.h"
- @interface TRStudent : NSObject
- @property(nonatomic,assign)int age;
- @property(nonatomic,copy)NSString* name;
- @property(nonatomic,copy)Book *book;
- -(id)initWithAge:(int)age andName:(NSString*)name andBook:(Book*)book;
- +(id)studentWithAge:(int)age andName:(NSString*)name andBook:(Book*)book;
- -(void)print:(id)condition;
- @end
类TRStudent实现,即TRStudent.m文件,完整代码如下所示:
- #import "TRStudent.h"
- @implementation TRStudent
- -(id)initWithAge:(int)age
- andName:(NSString*)name
- andBook:(Book*)book{
- self = [super init];
- if (self) {
- self.age = age;
- self.name = name;
- self.book = book;
- }
- return self;
- }
- +(id)studentWithAge:(int)age
- andName:(NSString*)name
- andBook:(Book*)book{
- return [[TRStudent alloc]initWithAge:age andName:name andBook:book];
- }
- -(void)print:(id)condition
- {
- bool a = [condition isKindOfClass:[NSNumber class]];
- bool b = [condition intValue] == self.age;
- bool c = [condition isKindOfClass:[NSString class]];
- bool d = [self.name isEqualToString:condition];
- if ((a && b) || (c && d))
- NSLog(@"stu name:%@, age:%d", self.name, self.age);
- }
- @end
主程序,即main.m,完整代码如下所示:
- #import <Foundation/Foundation.h>
- #import "TRStudent.h"
- int main(int argc, const char * argv[])
- {
- @autoreleasepool {
- // insert code here...
- //创建学生对象
- Book* book1 = [[Book alloc] init];
- book1.name = @"sanguo";
- book1.price = 20;
- TRStudent* stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan" andBook:book1];
- Book* book2 = [[Book alloc] init];
- book2.name = @"shuihu";
- book2.price = 18;
- TRStudent* stu2 = [TRStudent studentWithAge:19 andName:@"lisi" andBook:book2];
- Book* book3 = [[Book alloc] init];
- book3.name = @"xiyouji";
- book3.price = 28;
- TRStudent* stu3 = [TRStudent studentWithAge:20 andName:@"wangwu" andBook:book3];
- Book* book4 = [[Book alloc] init];
- book4.name = @"hongluomeng";
- book4.price = 24;
- TRStudent* stu4 = [TRStudent studentWithAge:21 andName:@"zhaoliu" andBook:book4];
- Book* book5 = [[Book alloc] init];
- book5.name = @"fengshenyanyi";
- book5.price = 22;
- TRStudent* stu5 = [TRStudent studentWithAge:22 andName:@"qianqi" andBook:book5];
- Book* book6 = [[Book alloc] init];
- book6.name = @"liaozhaizhiyi";
- book6.price = 15;
- TRStudent* stu6 = [TRStudent studentWithAge:23 andName:@"zhangfei" andBook:book6];
- Book* book7 = [[Book alloc] init];
- book7.name = @"sanxiawuyi";
- book7.price = 17;
- TRStudent* stu7 = [TRStudent studentWithAge:24 andName:@"guanyu" andBook:book7];
- Book* book8 = [[Book alloc] init];
- book8.name = @"yuefeizhuan";
- book8.price = 27;
- TRStudent* stu8 = [TRStudent studentWithAge:25 andName:@"zhaoyun" andBook:book8];
- //班级
- NSSet* class1403A = [NSSet setWithObjects:stu1,stu2,nil];
- NSSet* class1403B = [NSSet setWithObjects:stu3,stu4,nil];
- NSSet* class1403C = [NSSet setWithObjects:stu5,stu6,nil];
- NSSet* class1403D = [NSSet setWithObjects:stu7,stu8,nil];
- //学院
- NSSet* college3G = [NSSet setWithObjects:class1403A,class1403B,nil];
- NSSet* collegeTest = [NSSet setWithObjects:class1403C,class1403D,nil];
- //学校
- NSSet* tarena = [NSSet setWithObjects:college3G,collegeTest,nil];
- //遍历学校
- for (NSSet* college in tarena)
- {
- //遍历学院
- for (NSSet* class in college)
- {
- //遍历班级
- for (TRStudent* stu in class)
- {
- NSLog(@"stu name:%@, age:%d", stu.name, stu.age);
- }
- }
- }
- //遍历学校
- for (NSSet* college in tarena)
- {
- //遍历学院
- for (NSSet* class in college)
- {
- //输出年龄为18岁的学生信息
- [class makeObjectsPerformSelector:@selector(print:) withObject:[NSNumber numberWithInt:18]];
- //输出姓名为“张三”的学生信息
- [class makeObjectsPerformSelector:@selector(print:) withObject:@"zhangsan"];
- }
- }
- //遍历学校
- for (NSSet* college in tarena)
- {
- //遍历学院
- for (NSSet* class in college)
- {
- //遍历班级
- for (TRStudent* stu in class)
- {
- NSLog(@"book name:%@, price:%d", stu.book.name, stu.book.price);
- }
- }
- }
- }
- return 0;
- }
NSArray(二) 、 NSMutableArray 、 NSSet 、 NSMutableSet的更多相关文章
- NSArray,NSMutable和NSSet,NSMutableSet和NSDictionary,NSMutableDictionary用法
开始编写应用程序的代码时,可以利用大量的 Objective-C 框架.其中,为所有应用程序提供基本服务的 Foundation 框架尤为重要.Foundation 框架包括表示基本数据类型的值类(如 ...
- iOS阶段学习第15天笔记(NSArray与NSMutableArray 数组)
iOS学习(OC语言)知识点整理 一.OC中的数组 1)数组:也是一个对象,数组中存放的是对象的地址,可以存放任意类型对象的地址,只能是对象不能是具体的数值,数组是有序的, 可以存放重复的元 ...
- NSArray和NSMutableArray
//1. NSArray EOItems *eOItems = [[EOItems alloc] init]; eOItems.ID = [NSNumber numberWithInt:]; NSAr ...
- NSArray、NSMutableArray基本用法
NSArray.NSMutableArray基本用法 一.基本操作 初始化方法:1.init返回一个空数组 2.initWithArray从已有数组初始化 3.initWithContentsOfFi ...
- iOS7 CookBook精彩瞬间(二)NSSet、通过Subscript访问类成员等
1.NSSet的用法 ①NSSet是一种无序集合,基于hash实现,可以在线性时间复杂度内查找某个元素,如果要让元素有序,应当使用NSOrderedSet,要让集合可变,与NSArray类似,使用NS ...
- 集合对象(NSSet,NSMutableSet,NSIndexSet)
NSArray:有序的集合,NSSet:无序的集合,散列存储. 但是NSSet保证数据的唯一性.当插入相同的数据时,不会有任何效果.从内部实现来说是hash表.NSMutableSet是NSSet的子 ...
- NSArray和NSMutableArray的常用方法 (转)
NSArray和NSMutableArray的常用方法 (转) (2013-09-06 15:13:46) 标签: it 分类: ios编程 初始化方法: 1.init返回一个空数组 2.i ...
- --NSArray与NSMutableArray用copy修饰还是strong(转)
一.NSMutableArray 被copy.strong修饰后的变化: 把NSMutableArray用copy修饰有时就会crash,因为对这个数组进行了增删改操作,而copy后的数组变成了不可变 ...
- IOS数组NSArray与NSMutableArray知识点
此文是对数组NSArray与NSMutableArray知识点的总结,主要是一些常见的操作,别外一些操作见其相应的文档,下面的代码部分还运用的第三方插件BlocksKit相结合: a:Foundati ...
- 15.Object-C--浅谈Foundation框架OC数组NSArray与NSMutableArray
昨天总结了一下NSString与NSMutableString,今天我在这里总结一下NSArray与NSMutableArray. NSArray数组是:不可变数组. nil 是数组元素结束的标记.O ...
随机推荐
- boost 源码编译 的 Makefile.am写法备份
include $(top_srcdir)/common.mk bin_PROGRAMS= lib_LIBRARIES= lib_LTLIBRARIES= lib_LTLIBRARIES+=libSt ...
- 在Ios里UIWebView参入js
//修改图片大小适应webView宽高度 [webView stringByEvaluatingJavaScriptFromString: @"var sc ...
- 0302IT行业就业&软件工程之我所思和所想
阅读以下文章 http://www.thea.cn/news/terminal/9/9389.html http://www.shzhidao.cn/system/2015/09/22/0102610 ...
- C++-继承名称的掩盖
/////////////////////////////////////////////////////////////////////////////// // // FileName : eff ...
- HDU 3341 状态压缩DP+AC自动机
题目大意: 调整基因的顺序,希望使得最后得到的基因包含有最多的匹配串基因,使得所能达到的智商最高 这里很明显要用状态压缩当前AC自动机上点使用了基因的情况所能达到的最优状态 我最开始对于状态的保存是, ...
- 学好C++必须要注意的十八个问题
转自 http://blog.chinaunix.net/uid-7396260-id-2056691.html 一.#include "filename.h"和#i nclud ...
- powershell 判断操作系统版本 命令
powershell 传教士 原创文章.始于 2015-12-15 允许转载,但必须保留名字和出处,否则追究法律责任 一 前言 判断操作系统版本,是个老话题,bat.vbs中都有例子,这本不是重要问题 ...
- VS2010中添加lib库引用
VS2010中添加lib库引用: 1 菜单 项目---> 属性--->配置属性-->链接器---->输入---附加依赖项, 加入库名,如: my_API.lib; 或是在c ...
- ajax上传组件
BJUI框架的异步上传组件功能. 初始化: 1.Data属性:div添加属性data-toggle="upload"后可触发上传组件. 示例代码: <div class=&q ...
- python3使用requests发闪存
闪存ing.cnblogs.com是博客园类似推特.饭否的服务, 我写了以下程序可以完成发闪存的操作,目的是顺便练习使用requests库. requests是一个python 轻量的http客户端库 ...