类:NSObject 、NSString、NSMutableString、NSNumber、NSValue、NSDate、NSDateFormatter、NSRange、Collections:NSSet、NSArray(Ordered、Copy)、NSMutableArray、NSMutableSet、NSDictionary
========================================================================================
知识点
一、NSObject类
1.NSObject的概述
提供了系统运行时的一些基本功能
1.对象的创建、销毁
alloc init new dealloc
2. 类的初始化
1.类加载的时候,自动调用+load方法
2.第一次使用类的时候,自动调用+initailize方法
类在使用之前会执行此方法,并且只执行一次(直接可以在.m中调用此方法)
2.copy方法
1.并不是所有对象都有copy方法
2.如果一个对象支持copy功能,会将对象复制一份(深拷贝)
a.首先要遵守协议NSCopying协议.h文件,
b.必须实现copyWithZone方法协议.m文件
3.如果不但想复制对象,而且还要复制对象的值,
一般还要重写属性的有参的初始化方法,把self.参数值一起通过return返回
TRStudent.h
#import
@interface TRStudent : NSObject
@property int i;
-(id)initWithI:(int)i;
@end
TRStudent.m
#import "TRStudent.h"
@implementation TRStudent
+(void)load{
NSLog(@"load");
}
+(void)initialize{
NSLog(@"initialize");
}
//初始化方法
-(id)initWithI:(int)i{
if ([super init]) {
self.i=i;
}
return self;
}
//遵守NSCopying协议,实现方法
-(id)copyWithZone:(NSZone *)zone{
return [[TRStudent alloc]initWithI:self.i];//深拷贝属性
}
@end
main.m
#import
#import "TRStudent.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
TRStudent* p=[[TRStudent alloc]init];
p.i=10;
TRStudent *p2=p;//浅拷贝 指向的地址一样
TRStudent *p3=[p copy];//深拷贝,指向的地址不一样
NSLog(@"p:%p",p);
NSLog(@"p2:%p",p2);
NSLog(@"p3:%p %d",p3,p3.i);//深拷贝属性
}
return 0;
}
结果:
load
initialize
p:0x100601a80
p2:0x100601a80
p3:0x100600650 10
4.copy还可以用在声明式属性中,但是注意程序的本质发生改变,会自动向实例变量发送copy消息,实例变量必须遵守协议/实现
TRBook.h
#import
@interface TRBook : NSObject
@property(nonatomic,assign)int price;
@end
TRBook.m
#import "TRBook.h"
@implementation TRBook
-(id)initWithPrice:(int)price{
self = [super init];
if (self) {
self.price = price;
}
return self;
}
- (id)copyWithZone:(NSZone *)zone{
return [[TRBook alloc]initWithPrice:self.price];
}
@end
TRStudent.h
#import
#import "TRBook.h"
@interface TRStudent : NSObject
//@property(retain)TRBook *book;
@property(copy)TRBook *book;
-(void)study;
@end
TRStudent.m
#import "TRStudent.h"
@implementation TRStudent
-(void)study{
NSLog(@"学生看书 price:%d add:%p",self.book.price,self.book);
}
@end
main.m
TRBook *sanguo = [[TRBook alloc]init];
sanguo.price = 10;
NSLog(@"sanguo:%p",sanguo);
TRStudent *stu = [[TRStudent alloc]init];
stu.book = sanguo;
[stu study];
结果:
sanguo:0x100203af0
学生看书 price:10 add:0x1004006a0
二、类对象
1.类的对象:关注的是类的代码信息,需要比较类的数据的时候需要使用类的对象。
2.类对象:关注的是对象的数据信息,需要比较类的代码的时候需要使用类对象。
3.比较类信息
一、向类发送class消息,可以创建类对象。
Class class = [TRStudent class];
二、判断
1.判断一个引用指向的对象是否是某种类型或子类型
- (BOOL)isKindOfClass:(Class)c;
TRAnimal.h
#import
@interface TRAnimal : NSObject
-(void)eat;
@end
TRAnimal.m
#import "TRAnimal.h"
@implementation TRAnimal
-(void)eat{
NSLog(@"动物具有吃的能力");
}
@end
TRDog.h
#import "TRAnimal.h"
@interface TRDog : TRAnimal//继承了TRAnimal
@end
TRDog.m
TRPerson.h
#import
@interface TRPerson : NSObject//没有继承了TRAnimal
@end
TRPerson.m
main.m
#import
#import "TRAnimal.h"
#import "TRDog.h"
#import "TRPerson.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
TRAnimal *animal = [[TRDog alloc]init];
TRAnimal *animal2 = [[TRPerson alloc]init];
Class c = [TRAnimal class];//向类发送class消息,可以创建类对象
TRAnimal *animals[2] = {animal,animal2};
for (int i = 0; i<2; i++) {
//判断一个对象 是否是某系列类型
if ([animals[i] isKindOfClass:c]) {
[animals[i] eat];
}
}
}
return 0;
}
结果:
动物具有吃的能力
2.判断一个引用(实例)指向的对象是否是某种类型
-(BOOL)isMemberOfClass:(Class)c;
3.比较“类”信息的时候,需要使用类对象,判断一个类是否是另一个类的子类
+(BOOL)isSubclassOfClass:(Class)c;
main.m
@autoreleasepool {
TRAnimal *animal = [[TRDog alloc]init];
TRAnimal *animal2 = nil;
Class c = [TRAnimal class];
//判断TRPerson是否是TRAnimal的子类
//健壮性
if ([TRPerson isSubclassOfClass:c]) {
NSLog(@"TRPerson是TRAnimal的子类,可以使用多态");
animal2 = [[TRPerson alloc]init];
}else{
NSLog(@"TRPerson不是TRAnimal的子类,不可以使用多态");
}
}
结果:
TRPerson不是TRAnimal的子类,不可以使用多态
4.方法选择器
1.可以得到一个方法的引用。
SEL sel = @selector(study)//方法名
2.需要判断类中是否有某个方法
BOOL b = [TRStudent instancesRespondToSelector:@selector(study)];
3. 可以向对象发送任何消息,而不需要在编译的时候声明
[stu performSelector:sel];
例:
TRAnimal.h
#import
@interface TRAnimal : NSObject
-(void)eat;
@end
TRAnimal.m
#import "TRAnimal.h"
@implementation TRAnimal
-(void)eat{
NSLog(@"nihao");
}
@end
main.m
#import
#import "TRAnimal.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
TRAnimal *animal = [[TRAnimal alloc]init];
//代表一个方法
SEL sel = @selector(eat);
//判断一个类是否可以响应某个消息
//判断一个类是否有某个方法
BOOL isRespond = [TRAnimal instancesRespondToSelector:sel];
if (isRespond) {
NSLog(@"类中有eat消息,可以发送");
//[animal eat];
}else{
NSLog(@"类中没有eat消息,不可以发送");
}
[animal performSelector:sel];
}
return 0;
}
结果:
类中有eat消息,可以发送
nihao
5.协议选择器
1.协议的引用指向一个协议
Prtocol* p = @protocol(NSCopying);
2.可以判断一个类是否遵守了某个协议
BOOL b = [TRStudent conformsToProtocol:p];
#import
#import "TRProtocol.h"
#import "TRMyclass.h"
#import "TRStudent.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
// id
// [p1 eat];
Protocol*p=@protocol(TRProtocol);//协议名
if ([TRStudent conformsToProtocol:p]) {
NSLog(@"遵守了协议");
}
else{
NSLog(@"没有遵守协议");
}
}
return 0;
}
结果:
遵守了协议
=======================================================================
知识点
二、NSString
一、不可变字符串(NSString)
在新创建对象的基础上修改,就是又复制了一份
//创建字符串
NSString *str = @"hello";
NSString *str2 = @"hello";
NSLog(@"str addr:%p",str);
NSLog(@"str2 addr:%p",str2);
//将C语言中的字符串 转换成OC的字符串
NSString *str3 = [[NSString alloc]initWithCString:"hello"];
NSLog(@"str3 addr:%p",str3);
NSString *str4 = [[NSString alloc]initWithString:@"hello"];
NSLog(@"str4 addr:%p",str4);
//printf("%sworld","Hello");
NSString *str5 = [[NSString alloc]initWithFormat:@"%@",@"hello"];
结果:
str addr:0x100002060
str2 addr:0x100002060
str3 addr:0x100200d00
str4 addr:0x100002060
str5 addr:0x10010cd80
1.NSString的截取
#import
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSString * p=@"HelloWord";
NSString*p2=[p substringToIndex:5];//取头(从头到哪),to不包括下标内容
NSString*p3=[p substringFromIndex:5];//去尾(从哪到尾),from包括下标内容
NSLog(@"p2:%@ p3:%@",p2,p3);
NSRange r={4,3};//取中间,从哪长度是多少
NSString*p4=[p substringWithRange:r];
NSLog(@"p4:%@",p4);
}
return 0;
}
结果:
p2:Hello p3:Word
p4:oWo
练习:
//练习:230119197007010000
//求:年、月、日
//截取得到日期
NSString *sid = @"230119197007010000";
//在OC当中 创建结构有更简单的方式
//会有结构体函数解决这个问题
//NSMakeRange
NSRange range2 = NSMakeRange(6, 8);
NSString *date = [sid substringWithRange:range2];
NSLog(@"date:%@",date);
NSString *year = [date substringToIndex:4];
NSLog(@"year:%@",year);
NSString *month = [date substringWithRange:NSMakeRange(4, 2)];
NSLog(@"month:%@",month);
NSString *day = [date substringFromIndex:6];
NSLog(@"day:%@",day);
date:19700701
year:1970
month:07
day:01
2.字符串的拼接(初始化、追加、追加指定范围)
//字符串的拼接
NSString *str10 = @"Hello";
//追加
NSString *str11 = [str10 stringByAppendingString:@"World"];
NSLog(@"str11:%@",str11);
//初始化
NSString *str12 = @"Hello";
NSString *str13 = @"World";
NSString *str14 = [NSString stringWithFormat:@"%@%@",str12,str13];
NSString *str15 = [NSString stringWithFormat:@"Hello%@",str13];
NSLog(@"str14:%@",str14);
NSLog(@"str15:%@",str15);
//按指定格式(范围)追加内容
NSString *str16 = @"Hello";
NSString *str17 = [str16 stringByAppendingFormat:@"%@%@",@"World",@"123"];
NSLog(@"str17:%@",str17);
结果:
str11:HelloWorld
str14:HelloWorld
str15:HelloWorld
str17:HelloWorld123
3.字符串替换
//替换
NSString *str18 = @"www.tarena.com.cn";
NSString *str19 = [str18 stringByReplacingCharactersInRange:NSMakeRange(4, 6) withString:@"163"];
NSLog(@"str19:%@",str19);
结果:
str19:www.163.com.cn
4.字符串的编码集
通过文件内容创建字符串,注意存在编码集的问题,默认为 ASC(不包含中文),要指定相应的中文编码集(GBK简体中文、 GB2312简体中文、BIG5繁体中文、UTF8全世界主流语言...)
参数1 文件的路径
参数2 指定文件的编码集
参数3 出现异常处理
//编码集
//参数 文件的路径 不包括文件名
NSString *path = @"/Users/tarena/Desktop";
//path = [path stringByAppendingString:@"/test.txt"];
path = [path stringByAppendingString:@"/test2.rtf"];
//把文件中的内容 读取到字符串中
//NSString *str20 = [[NSString alloc]initWithContentsOfFile:path];
NSString *str21 = [[NSString alloc]initWithContentsOfFile:path encoding:NSUTF8 StringEncoding error:nil];
NSLog(@"str21:%@",str21);
5.字符串比较
BOOL b=[str isEqualToString:stu2]//stu和stu2比较,比较的是字符串的内容
注:==只可以比较两个字符串的地址
main.m
@autoreleasepool {
NSString* use=@"fcp";
NSString* use1=@"fcp";
NSString*password=@"123";
NSString*password1=@"123";
if ([use isEqualToString:use1]&&[password isEqualToString:password1]) {
NSLog(@"登陆成功");
}
else{
NSLog(@"登陆失败");
}
}
结果:登陆失败
二、可变字符串(NSMutableString)
是NSString的子类,NSString的功能都继承,对字符串的修改是在原字符串的基础上
c语言对象(数据)改变 CRUD 创建 查看 修改 删除
oc数据改变 添加 删除 替换
1.可变字符串的创建
//字符串的创建
//在可变字符串中 空字符串就有意义
NSMutableString *mString = [[NSMutableString alloc]init];
//可变字符串不可以与代码区的字符串赋值使用
//NSMutableString *mString2 = @"Hello";mString2将退化成NSString
//可以指定字符串的空间大小 创建字符串
NSMutableString *mString3 =[NSMutableString stringWithCapacity:30];
2.添加内容(插入)
参数1:添加的内容
参数2:替换的长度
//可变字符串 添加内容
NSMutableString *mString4 = [[NSMutableString alloc]initWithString:@"Hello"];
[mString4 appendString:@"World"];//给mString4拼接
NSLog(@"mString4:%@",mString4);
//可以在指定位置 添加字符串内容
[mString4 insertString:@"123" atIndex:5];
NSLog(@"mString4:%@",mString4);
结果:
mString4:HelloWorld
mString4:Hello123World
3.删除内容
//删除内容
NSMutableString *mString5 = [[NSMutableString alloc]initWithString:@"I am learning Objective-C language."];
//查找字符串内容,在所在字符串中的位置
NSRange range = [mString5 rangeOfString:@"learn"];//需要删除的内容
NSLog(@"range: loc:%lu length:%lu",range.location,range.length);
//删除可变字符串中指定的内容
[mString5 deleteCharactersInRange:range];
NSLog(@"mString5:%@",mString5);
结果:
range: loc:5 length:5
mString5:I am ing Objective-C language.
3.替换内容
参数1:(位置,长度)
参数2:替换内容
//替换内容
NSMutableString *mString6 = [[NSMutableString alloc]initWithString:@"HelloWorld!"];
[mString6 replaceCharactersInRange:NSMakeRange(4, 3) withString:@"1234"];
NSLog(@"mString6:%@",mString6);
结果:
mString6:Hell1234rld!
======================================================================================
知识点
三、类型转换(NSNumber)
在很多类使用的时候,如果使用数值,就需要将数值转换成对象类型
1.int类型的转换
1.封装方法
+ (NSNumber *)numberWithInt:(int)value;
+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
2.拆封方法
- (int)intValue;
- (unsigned int)unsignedIntValue;
例:
#import
int main(int argc, const char * argv[])
{
@autoreleasepool {
int i=10;
//封装 将基本数据类型封装成数值对象类型
NSNumber* number=[NSNumber numberWithInt:i];
NSLog(@"%@",number);
//拆封
int i2=[number intValue];
NSLog(@"%d",i2);
}
return 0;
}
结果:
10
10
2.chan类型转换
1.封装方法
+ (NSNumber *)numberWithChar:(char)value;
+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
2.拆封方法
- (char)charValue;
- (unsigned char)unsignedCharValue;
3.float类型转换
4.double类型转换
5.BOOL类型转换
1.封装方法
+ (NSNumber *)numberWithBool:(BOOL)value;
2.拆封方法
- (BOOL)boolValue;
========================================================================
知识点
四、NSValue
1.有时需要创建一个对象,以密切反应原始数据类型或者数 据结构,这种情况就需要使用NSValue类,它可以将任何 C中有效的变量类型封装成对象类型。
2. NSNumber是NSValue的子类
1.将自定义类型转换
通过NSValue类,将结构类型封装成NSValue对象
参数1 结构体变量的内存地址
参数2 内存地址对应的结构体类型
#import
int main(int argc, const char * argv[])
{
@autoreleasepool {
//定义一个结构体类型
typedef struct{
int x;
int y;
}TRPoint;
//c语言中自动义数据类型 声明一个结构变量并且赋值
TRPoint point={6,5};
//封装成OC语言中的对象类型
//通过NSValue类,将结构类型封装成NSValue对象
NSValue* value=[NSValue valueWithBytes:&point objCType:@encode(TRPoint)];
//解封 参数1 参数2
TRPoint point2;
[value getValue:&point2];
NSLog(@"x:%d y:%d",point2.x,point2.y);
}
return 0;
}
结果:x:6 y:5
=====================================================================================================================================
知识点
五、NSDate(日期)
NSDate存储的是时间信息,默认存储的是世界标准时间 (UTC),输出时需要根据时区转换为本地时间。中国大陆、香 港、澳门、台湾...的时间增均与UTC时间差为+8,也就是 UTC+8
//日期
NSDate* date=[[NSDate alloc]init];//得到当前时间
NSLog(@"%@",date);
NSDate* date2=[NSDate dateWithTimeIntervalSinceNow:30];//和当前比延迟30秒
NSDate* date3=[NSDate dateWithTimeIntervalSinceNow:-60*60*24];//昨天
NSDate* date4=[NSDate dateWithTimeIntervalSinceNow:60*60*24];//明天
NSLog(@"%@",date2);
NSLog(@"%@ %@",date3,date4);
结果:
2015-01-26 08:26:34 +0000今天
2015-01-26 08:27:04 +0000
2015-01-25 08:26:34 +0000昨天
2015-01-27 08:26:34 +0000明天
=====================================================================================================================================
知识点
六、NSDateFormatter
利用它可以指定所需的任何类型的行为, 并将指定的NSDate对象转换成与所需行为匹配的日期 的相应字符串表示
//转换时间模板
NSDateFormatter*dateFormatter=[[NSDateFormatter alloc]init];
//hh12小时制mm分钟ss秒 HH24小时制 //MM月dd日yyyy年
dateFormatter.dateFormat=@"yyyy-MM-dd hh:mm:ss";
//时间对象的转换
NSDate* date=[[NSDate alloc]init];
NSString*strDate=[dateFormatter stringFromDate:date];
NSLog(@"%@",strDate);
结果:
2015-01-26 04:48:30
练习:年龄 = 当前时间 - 出生年
根据身份证号 得到一个人的年龄
230110197007010000
#import
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSDate *now = [NSDate date];
//创建时间模板对象
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
//指定模板格式
//yyyy MM dd hh mm ss 年月日时分秒
//formatter.dateFormat = @"hh小时mm分钟ss秒 yyyy-MM-dd";
formatter.dateFormat = @"yyyy";
//转换时间 按指定格式转换时间 转换本地时间
NSString *strDate = [formatter stringFromDate:now];
NSLog(@"strDate:%@",strDate);
//练习:年龄 = 当前时间 - 出生年
//根据身份证号 得到一个人的年龄
//230110197007010000
NSString *sid = @"230119199907010000";
//在OC当中 创建结构有更简单的方式
//会有结构体函数解决这个问题
//NSMakeRange
NSRange range2 = NSMakeRange(6, 8);
NSString *date = [sid substringWithRange:range2];
NSLog(@"date:%@",date);
NSString *year = [date substringToIndex:4];
int nowDate = [strDate intValue];
int idDate = [year intValue];
int yearsOld = nowDate-idDate;
NSLog(@"age:%d",yearsOld);
}
return 0;
}
结果:
strDate:2015
date:19990701
age:16
====================================================================================================================================
知识点
七、集合类(Collections)
一.NSSet
1.是一个无序的,管理多个对象的集合类,最大特点 是集合中不允许出现重复对象,和数学上的集合含义是一 样的
2.除了无序、不许重复之外,其它功能和NSArray是一样的
二.NSArray
1.数组是一组有序的集合,
2.通过索引下标取到数组中的各个元素,与字符串相同,
3.数组也有可变数组 (NSMutableArray)和不可变数组(NSArray),
4.数组中不可以保存基本数据类型、结构体数据类型,需要使用 NSNumber和NSValue进行数据“封装
1.NSArray的创建(4种)
1.普通字符串数组
NSString* str1=@"one";
NSString* str2=@"two";
NSString* str3=@"three";
NSArray* array1=[[NSArray alloc]initWithObjects:str1,@"two",str3,nil];//保存的都是地址
NSLog(@"%@",array1);
结果:
(
one,
two,
three
)
2.数组值是对象
**如果需要输出对象时,输出对象的属性值,要自己重写description方法
TRMyClass.h
#import
@interface TRMyClass : NSObject
@property(nonatomic,assign)int i;
@property(nonatomic,copy)NSString *str;
@end
TRMyClass.m
#import "TRMyClass.h"
@implementation TRMyClass
//要自己重写description方法
-(NSString *)description{
return [NSString stringWithFormat:@"i:%d str:%@",self.i,self.str];
}
@end
main.m
NSString *str1 = @"one";
TRMyClass *myClass = [[TRMyClass alloc]init];
myClass.i = 10;
myClass.str = @"ABC";
NSLog(@"myClass:%@",myClass);
//如果需要输出对象时,输出对象的属性值,要自己重写description方法
NSString *str2 = @"two";
NSString *str3 = @"three";
//int array[3] = {1,2,3};
NSArray *array2 = [[NSArray alloc]initWithObjects:@"one",str2,str3,myClass, nil];
NSLog(@"array2:%@",array2);
结果:
array2:(
one,
two,
three,
"i:10 str:ABC"
)
3.通过一个以有的数组 创建一个新的数组
//通过一个以有的数组 创建一个新的数组
NSArray *array3 = [[NSArray alloc]initWithArray:array2];array2是上边的数组
NSLog(@"array3:%@",array3);
结果:同上
4.二维数组
//数组中的元素还可以是对象(数组本身也是对象)
//二维数组
NSArray *array4 = [NSArray arrayWithObject:array2];
结果:同上
5.数组添加元素,元素为数组
NSArray *array = @[@"one",@"two",@"three"];
//@1->[NSNumber numberWithInt:1]
//@基本数据类型->引用类型
NSArray *array2 = @[@'c',@2,@3,@YES];
//添加"一个"数组元素
NSArray *array3 = [array arrayByAddingObject:array2];
NSLog(@"array3:%@",array3);
//添加"一组"元素
NSArray *array4 = [array arrayByAddingObjectsFromArray:array2];
NSLog(@"array4:%@",array4);
结果:
array3:( 作为一个元素
one,
two,
three,
(
99,
2,
3,
1
)
)
array4:( 成为其中一个对象
one,
two,
three,
99,
2,
3,
1
)
2.数组的遍历
//数组的遍历
//array2.count == [array2 count]求数组的长度 array2是上边的数组
for (int i = 0; i<[array2 count]; i++) {
//array[]
if (i==2) {
continue;
}
id obj = [array2 objectAtIndex:i];//通过下标得到数组
NSLog(@"obj:%@",obj);
}
结果:
obj:one
obj:two
obj:i:10 str:ABC
**3.OC中遍历数组方式
a、c语言中的遍历方式
b、快速枚举OC
参数1:每次得到数组中元素的引用
参数2:哪一个集合/组合(数组引用对象)
c、迭代器遍历OC
可以得到数组或集合相应的替代器
#import
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSArray *array = [NSArray arrayWithObjects:@"one",@"two",@"three", nil];
//1.C语言中的遍历方式
for (int i = 0; i<[array count]; i++) {
NSLog(@"array[%d]:%@",i,[array objectAtIndex:i]);
}
//2.***快速枚举
//参数1 每次得到数组中元素的引用
//参数2 哪一个集合/组合
for (NSString *str in array) {
NSLog(@"str:%@",str);
}
//3.迭代器遍历
//可以得到数组或集合相应的替代器
NSEnumerator *enumertator = [array objectEnumerator];
//得到迭代器指向的内存空间的引用
//并且会自动向下移动一位,当超出数组或集合的范围则返回nil值
//[enumertator nextObject];
NSString *str = nil;
while (str = [enumertator nextObject]) {
NSLog(@"str2:%@",str);
}
//重构 学生与学校的故事
}
return 0;
}
str:one
str:two
str:three
练习:
学校和学生的故事
根据条件 筛选
#import
#import "TRStudent.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
//学生
TRStudent *stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan"];
TRStudent *stu2 = [TRStudent studentWithAge:22 andName:@"li"];
TRStudent *stu3 = [TRStudent studentWithAge:19 andName:@"zhaoliu"];
TRStudent *stu4 = [TRStudent studentWithAge:19 andName:@"wangwu"];
TRStudent *stu5 = [TRStudent studentWithAge:20 andName:@"qianqi"];
TRStudent *stu6 = [TRStudent studentWithAge:21 andName:@"guanyu"];
TRStudent *stu7 = [TRStudent studentWithAge:20 andName:@"zhangfei"];
TRStudent *stu8 = [TRStudent studentWithAge:18 andName:@"liubei"];
//创建班级
NSArray *class1412A = [NSArray arrayWithObjects:stu1,stu2, nil];
NSArray *class1412B = [NSArray arrayWithObjects:stu3,stu4, nil];
NSArray *class1412C = [NSArray arrayWithObjects:stu5,stu6, nil];
NSArray *class1412D = [NSArray arrayWithObjects:stu7,stu8, nil];
//学院
NSArray *college3G = [NSArray arrayWithObjects:class1412A,class1412B, nil];
NSArray *collegeTest = [NSArray arrayWithObjects:class1412C,class1412D, nil];
//学校
NSArray *universityTarena = [NSArray arrayWithObjects:college3G,collegeTest, nil];
NSLog(@"universityTarena:%@",universityTarena);
//遍历
//学校
for (int i = 0; i<[universityTarena count]; i++) {
NSArray *college =[universityTarena objectAtIndex:i];
//学院
for (int j = 0; j<[college count]; j++) {
NSArray *class = [college objectAtIndex:j];
//班级
for (int k = 0; k<[class count]; k++) {
TRStudent *stu = [class objectAtIndex:k];
//根据条件进行输出筛选
//根据年龄进行筛选等于18
if ([stu.name isEqualToString:@"zhangsan"]) {
NSLog(@"stu name:%@ age:%d",stu.name,stu.age);
}
}
}
}
}
return 0;
}
结果:
universityTarena:(
(
(
"age:18 name:zhangsan",
"age:22 name:li"
),
(
"age:19 name:zhaoliu",
"age:19 name:wangwu"
)
),
(
(
"age:20 name:qianqi",
"age:21 name:guanyu"
),
(
"age:20 name:zhangfei",
"age:18 name:liubei"
)
)
)
stu name:zhangsan age:18
**oc中数组遍历嵌套
//迭代器
NSEnumerator *enumerator=[university objectEnumerator];
NSArray *str=nil;
while (str=[enumerator nextObject]) {
//学院
NSEnumerator *enumerator1=[str objectEnumerator];
NSArray *str2=nil;
while (str2=[enumerator1 nextObject]) {
//班级
NSEnumerator *enumerator2=[str2 objectEnumerator];
TRStudent *str3=nil;
while (str3=[enumerator2 nextObject]) {
NSLog(@"%@",str3);
}
}
}
=====================================================================
//枚举遍历
for (NSArray* stu11 in university) {
for (NSArray* stu22 in stu11) {
//NSArray*class=stu22;
for (TRStudent* stu33 in stu22) {
NSLog(@"%@",stu33);
}
}
}
======================================================================================
***快速枚举与迭代器在执行的过程中不能直接删除元素,需要把元素先保存起来,需等到枚举结束,才可以删除
TRStudent *s=nil;
for ( TRStudent* a in class) {
if ([a.name isEqualToString:@"lisi"]) {
s=a;
//[class removeObject:a];不可以直接在枚举中删除
NSLog(@"%@",a);
}
}
[class removeObject:s];
NSLog(@"%@",class);
**当数组中有多个元素重复,使用此方法
NSMutableArray *removeStrs = [NSMutableArray array];
for (NSString *str in array) {
if ([str isEqualToString:@"two"]) {
//临时保存要删除的内容
[removeStrs addObject:str];
}
NSLog(@"str:%@",str);
}
//[array removeObject:removeStr];
for (NSString *removeStr in removeStrs) {
[array removeObject:removeStr];
}
NSLog(@"array:%@",array);
3.查询某个对象在数组中的位置
//返回数组中最后一个对象
id lastObj = [array2 lastObject];
NSLog(@"lastObj:%@",lastObj);
//查询某个对象在数组中的位置
NSUInteger index = [array2 indexOfObject:str3];array2是上边的数组
NSLog(@"index:%lu",index);
//通过下标得到数组
NSString* objStr=[array1 objectAtIndex:0];
//求数组长度
NSUInteger l=[stus count];
NSLog(@"%lu",(unsigned long)l);
结果:
lastObj:i:10 str:ABC
index:2
练习:
现在有一些数据,它们是整型数据10、字符型数据 ‘a’、单精度浮点型数据10.1f和自定义类TRStudent的一 个对象,将它们存放在数组NSArray中
TRStudent.h
TRStudent.m
main.m
#import
#import "TRStudent.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
//转换成数值对象
NSNumber* num1=[NSNumber numberWithInt:10];
NSNumber* num2=[NSNumber numberWithChar:'a'];
NSNumber* num3=[NSNumber numberWithFloat:10.1f];
NSLog(@"%@ %@ %@",num1,num2,num3);
TRStudent* stu=[[TRStudent alloc]init];
//遍历数组
NSArray* array=[[NSArray alloc]initWithObjects:num1,num2,num3,stu, nil];
for (int i=0; i<[array count]; i++) {
id job=[array objectAtIndex:i];
NSLog(@"%@",job);
}
}
return 0;
}
三、Ordered(数组排序)
1.排序规则本质(系统默认升序,如需降序,在NSOrderedAscending前加个减号)
’NSString *str = @"aad";
NSString *str2 = @"aac";
NSComparisonResult cr = [str compare:str2];
switch (cr) {
case NSOrderedAscending:
NSLog(@"str break; case NSOrderedSame: NSLog(@"str=str2"); break; case NSOrderedDescending: NSLog(@"str>str2"); break; } 结果:str>str2 2.排序规则 NSString *str11 = @"1"; NSString *str12 = @"5"; NSString *str13 = @"3"; NSArray *array = [NSArray arrayWithObjects:str11,str12,str13, nil]; NSLog(@"array:%@",array); //排序规则 SEL cmp = @selector(compare:); //得到排好序的新数组 NSArray *array2 = [array 结果: array:( 1, 5, 3 ) array2:( 1, 3, 5 ) 练习1:向数组中放入数字8 3 2 1 5 进行排序 NSNumber *num1 = [NSNumber numberWithInt:8]; NSNumber *num2 = [NSNumber numberWithInt:3]; NSNumber *num3 = [NSNumber numberWithInt:2]; NSNumber *num4 = [NSNumber numberWithInt:1]; NSNumber *num5 = [NSNumber numberWithInt:5]; NSArray *array3 = [NSArray arrayWithObjects:num1,num2,num3,num4,num5, nil]; NSLog(@"array3:%@",array3); NSArray *array4 = [array3 sortedArrayUsingSelector:@selector(compare:)]; NSLog(@"array4:%@",array4); 结果: array4:( 1, 2, 3, 5, 8 ) 练习2:创建一个自定义类TRStudent,为该类生成五个对象。 把这五个对象存入一个数组当中,然后按照姓名、年龄对五个对象 进行排序。 TRStudent.h #import @interface TRStudent : NSObject @property(nonatomic,assign)int age; @property(nonatomic,copy)NSString *name; -(id)initWithAge:(int)age andName:(NSString*)name; +(TRStudent*)studentWithAge:(int)age andName:(NSString*)name; //排序规则 //比较年龄 -(NSComparisonResult)compare:(TRStudent*)otherStudent; //比较姓名 -(NSComparisonResult)compareName:(TRStudent *)otherStudent; //先年龄后姓名 -(NSComparisonResult)compareAgeAndName:(TRStudent *)otherStudent; @end TRStudent.m #import "TRStudent.h" @implementation TRStudent -(id)initWithAge:(int)age andName:(NSString*)name{ self = [super init]; if (self) { self.age = age; self.name = name; } return self; } +(TRStudent*)studentWithAge:(int)age andName:(NSString*)name{ return [[TRStudent alloc]initWithAge:age andName:name]; } -(NSString *)description{ return [NSString stringWithFormat:@"age:%d name:%@",self.age,self.name]; } //制定年龄的比较规则 //按姓名比较? //如果年龄相同再按姓名比较? //如果姓名相同再按年龄比较? -(NSComparisonResult)compare:(TRStudent*)otherStudent{ if(self.age>otherStudent.age){ return NSOrderedDescending; }else if (self.age == otherStudent.age){ return NSOrderedSame; }else{ return NSOrderedAscending; } } -(NSComparisonResult)compareName:(TRStudent *)otherStudent{ return [self.name compare:otherStudent.name]; } -(NSComparisonResult)compareAgeAndName:(TRStudent *)otherStudent{ //先比较年龄 if(self.age>otherStudent.age){ return NSOrderedDescending; }else if (self.age == otherStudent.age){ //比较姓名 return [self.name compare:otherStudent.name]; }else{ return NSOrderedAscending; } } @end main.m #import #import "TRStudent.h" int main(int argc, const char * argv[]) { @autoreleasepool { TRStudent *stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan"]; TRStudent *stu2 = [TRStudent studentWithAge:22 andName:@"li"]; TRStudent *stu3 = [TRStudent studentWithAge:19 andName:@"zhaoliu"]; TRStudent *stu4 = [TRStudent studentWithAge:19 andName:@"wangwu"]; TRStudent *stu5 = [TRStudent studentWithAge:20 andName:@"qianqi"]; NSArray *stus = [NSArray arrayWithObjects:stu1,stu2,stu3,stu4,stu5, nil]; NSLog(@"stus:%@",stus); NSArray *stus2 = [stus sortedArrayUsingSelector:@selector(compare:)]; NSLog(@"stu2:%@",stus2); NSArray *stus3 = [stus sortedArrayUsingSelector:@selector(compareName:)]; NSLog(@"stu3:%@",stus3); NSArray *stus4 = [stus sortedArrayUsingSelector:@selector(compareAgeAndName:)]; NSLog(@"stu4:%@",stus4); } return 0; } 结果: stu4:( "age:18 name:zhangsan", "age:19 name:wangwu", "age:19 name:zhaoliu", "age:20 name:qianqi", "age:22 name:li" 四、数组的拷贝 - 数组的复制分为: 1.深拷贝(内容复制):将对象生成副本 2.浅拷贝(引用复制):仅将对象的引用计数加1 - 数组中的元素,对象的引用 TRStudent.h #import @interface TRStudent : NSObject @property(nonatomic,assign)int age; @property(nonatomic,copy)NSString*name; -(id)initWithAge:(int)age andName:(NSString*)name; +(TRStudent*)studentWithAge:(int)age andName:(NSString*)name; @end TRStudent.m #import "TRStudent.h" @implementation TRStudent -(id)initWithAge:(int)age andName:(NSString*)name{ if ([super init]) { self.age=age; self.name=name; } return self; } +(TRStudent*)studentWithAge:(int)age andName:(NSString*)name{ return [[TRStudent alloc]initWithAge:age andName:name]; } //重写description方法,解决返回数值问题 /* -(NSString *)description{ return [NSString stringWithFormat:@"age:%d name:%@",self.age,self.name]; } */ //遵守cope协议 -(id)copyWithZone:(NSZone *)zone{ return [[TRStudent alloc]initWithAge:self.age andName:self.name]; } @end main.m #import #import "TRStudent.h" int main(int argc, const char * argv[]) { @autoreleasepool { TRStudent *stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan"]; TRStudent *stu2 = [TRStudent studentWithAge:22 andName:@"li"]; TRStudent *stu3 = [TRStudent studentWithAge:19 andName:@"zhaoliu"]; TRStudent *stu4 = [TRStudent studentWithAge:19 andName:@"wangwu"]; TRStudent *stu5 = [TRStudent studentWithAge:20 andName:@"qianqi"]; NSArray *stus = [NSArray arrayWithObjects:stu1,stu2,stu3,stu4,stu5, nil]; NSLog(@"stus:%@",stus); //浅拷贝 NO /* TRStudent *stu = [[TRStudent alloc]init]; TRStudent *stu2 = stu; */ NSArray *stus2 = [[NSArray alloc]initWithArray:stus copyItems:NO];//浅拷贝 NSLog(@"stus2:%@",stus2); //深拷贝 YES //数组的深拷贝要依赖于对象的深拷贝 //对象的深拷贝(1.NSCopying 2.copyWithZone)(需要遵守copy协议) NSArray *stus3 = [[NSArray alloc]initWithArray:stus copyItems:YES]; NSLog(@"stus3:%@",stus3); } return 0; } 结果: ( " " " " " ) ( " " " " " ) ( " " " " " ) ===================================================================================================== 重写description方法,解决返回数值问题 -(NSString *)description{ return [NSString stringWithFormat:@"age:%d name:%@",self.age,self.name]; } ================================================================================================================================================================================ 知识点 八、NSMutableArray(可变数组) 1.NSMutableArray(可变数组) 是Objective-C定义的可修改数组类 – 是NSArray的子类 2.创建数组 NSMutableArray* array=[NSMutableArray arrayWithObjects:@"one",@"two",@"three", nil]; 3.添加元素 1.在数组末尾添加对象 2.在指定位置插入对象 #import int main(int argc, const char * argv[]) { @autoreleasepool { NSMutableArray* array=[NSMutableArray arrayWithObjects:@"one",@"two",@"three", nil]; [array addObject:@"four"];//在数组末尾添加对象 NSLog(@"%@",array); [array insertObject:@"five" atIndex:3];//插入对象 NSLog(@"%@",array); } return 0; } 结果: ( one, two, three, four ) ( one, two, three, five, four ) 4.修改元素 1.在指定位置修改元素 2.用另一数组替换指定范围对象 NSMutableArray* array=[NSMutableArray arrayWithObjects:@"one",@"two",@"three", nil]; [array replaceObjectAtIndex:1 withObject:@"six"];//在指定位置修改元素 NSLog(@"%@",array); //用另一数组替换指定范围对象 NSMutableArray* array2=[NSMutableArray arrayWithObjects:@"1",@"2",@"3", nil]; NSRange r={2,1}; [array replaceObjectsInRange:r withObjectsFromArray:array2]; NSLog(@"%@",array); 结果: ( one, six, three ) ( one, six, 1, 2, 3 ) 5.删除元素 1.最后一个对象 [array removeLastObject]; 2.指定对象 [array removeObject:@"two"]; 3.指定位置对象 [array removeObjectAtIndex:2]; 4.指定范围对象 NSRange r = {1, 2}; [array removeObjectsInRange:r]; 5.清空数组 [array removeAllObjects]; //删除数组中的元素 /*1,2,3,five,four*/ [mArray removeLastObject]; NSLog(@"mArray:%@",mArray); [mArray removeObject:@"five"]; NSLog(@"mArray:%@",mArray); [mArray removeObjectAtIndex:1]; NSLog(@"mArray:%@",mArray); [mArray removeObjectsInRange:NSMakeRange(0, 2)]; NSLog(@"mArray:%@",mArray); 结果: mArray1:( 1, 2, 3, five ) mArray2:( 1, 2, 3 ) mArray3:( 1, 3 ) mArray4:( ) 练习: #import #import "TRStudent.h" int main(int argc, const char * argv[]) { @autoreleasepool { TRStudent* stu1=[TRStudent studentWithAge:18 andName:@"zhangsan"]; TRStudent* stu2=[TRStudent studentWithAge:20 andName:@"lisi"]; NSMutableArray* class=[NSMutableArray arrayWithObjects:stu1,stu2, nil]; //添加学生 TRStudent* stu3=[TRStudent studentWithAge:19 andName:@"zhaoliu"]; [class addObject:stu3]; NSLog(@"%@",class); //删除学生 lisi //[class removeObjectAtIndex:0]; //遍历数组 for (int i=0; i<[class count]; i++) { TRStudent* stu=[class objectAtIndex:i]; if ([stu.name isEqualToString:@"lisi"]) {//筛选出学生 [class removeObject:stu];//删除学生 NSLog(@"%@",class); } } } return 0; } 结果: ( "age:18 name:zhangsan", "age:20 name:lisi", "age:19 name:zhaoliu" ) ( "age:18 name:zhangsan", "age:19 name:zhaoliu" ) 6.ios6 新语法 a.ios6.0及osx10.8之后,编译器LLVM支持。 b.初始化数据 OC:[NSArray arrayWithObject…@“a”]; OC新:@[@“a”,@“b”]; C语言:{“a”,“b”}; c.取元素的值 OC:[数组对象 objectAtIndex…]; OC新:数组对象[下标]; d.基本类型转换数值对象 OC:@1->[NSNumber numberWithInt:1] OC新:NSArray *array2 = @[@'c',@2,@3,@YES]; #import int main(int argc, const char * argv[]) { @autoreleasepool { //初始化 NSArray *array = [NSArray arrayWithObjects:@"one",@"two",@"three", nil]; //ios6中的新语法 NSArray *array2 = @[@"one",@"two",@"three"]; //不允许将父类类型赋值给子类类型 //NSMutableArray *array3 = @[@"one",@"two",@"three"]; *将不可变数组转换为可变数组 //将不可变数组转换为可变数组 NSMutableArray *array3 =[@[@"one",@"two",@"three"]mutableCopy]; //取元素的值 NSString *str = [array objectAtIndex:0]; //ios6中的新语法 NSString *str2 = array[0]; } return 0; } 作业: 1.重构 使用ios6新语法 学生与学校的故事。 2.重构 使用三种遍历方式 #import #import "TRStudent.h" int main(int argc, const char * argv[]) { @autoreleasepool { //学生 TRStudent *stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan"]; TRStudent *stu2 = [TRStudent studentWithAge:22 andName:@"li"]; TRStudent *stu3 = [TRStudent studentWithAge:19 andName:@"zhaoliu"]; TRStudent *stu4 = [TRStudent studentWithAge:19 andName:@"wangwu"]; TRStudent *stu5 = [TRStudent studentWithAge:20 andName:@"qianqi"]; TRStudent *stu6 = [TRStudent studentWithAge:21 andName:@"guanyu"]; TRStudent *stu7 = [TRStudent studentWithAge:20 andName:@"zhangfei"]; TRStudent *stu8 = [TRStudent studentWithAge:18 andName:@"liubei"]; //班级 NSArray *class1=@[stu1,stu2]; NSArray *class2=@[stu3,stu4]; NSArray *class3=@[stu5,stu6]; NSArray *class4=@[stu7,stu8]; //学院 NSArray *college1=@[class1,class2]; NSArray *college2=@[class3,class4]; //学校 NSArray *university=@[college1,college2]; /**/ //c语言遍历数组 for (int i=0; i<[university count]; i++) { NSArray* college=university[i]; //学院 for (int j=0; j<[college count]; j++) { NSArray* class="college"[j]; //班级 for (int k=0; k<[class count]; k++) { TRStudent*stu=class[k]; NSLog(@"%@",stu); } } } /**/ //枚举遍历 for (NSArray* stu11 in university) { for (NSArray* stu22 in stu11) { //NSArray*class=stu22; for (TRStudent* stu33 in stu22) { NSLog(@"%@",stu33); } } } //迭代器 NSEnumerator *enumerator=[university objectEnumerator]; NSArray *str=nil; while (str=[enumerator nextObject]) { //学院 NSEnumerator *enumerator1=[str objectEnumerator]; NSArray *str2=nil; while (str2=[enumerator1 nextObject]) { //班级 NSEnumerator *enumerator2=[str2 objectEnumerator]; TRStudent *str3=nil; while (str3=[enumerator2 nextObject]) { NSLog(@"%@",str3); } } } } return 0; } 3.National类 有名称China,拥有多个地区,有地区 Area(名称、人口) 创建三个地区 (beijing 3000 guangzhou 2000 shanghai 2200) 显示所有城市及人口 只显示北京的人口 重构... ios6新语法 遍历三种方式 TRNational.h #import @interface TRNational : NSObject @property(nonatomic,copy)NSString *name; @property(nonatomic,strong)NSMutableArray *areas; @end TRNational.m #import "TRNational.h" @implementation TRNational @end TRArea.h #import @interface TRArea : NSObject @property(nonatomic,copy)NSString *name; @property(nonatomic,assign)int population; -(id)initWithName:(NSString*)name andPopulation:(int)population; +(id)areaWithName:(NSString*)name andPopulation:(int)population; @end TRArea.m #import "TRArea.h" @implementation TRArea -(id)initWithName:(NSString*)name andPopulation:(int)population{ self = [super init]; if (self) { self.name = name; self.population = population; } return self; } +(id)areaWithName:(NSString*)name andPopulation:(int)population{ return [[TRArea alloc]initWithName:name andPopulation:population]; } @end main.m #import #import "TRNational.h" #import "TRArea.h" int main(int argc, const char * argv[]) { @autoreleasepool { TRNational *n = [[TRNational alloc]init]; n.name = @"china"; //一个对象中的属性 如果是对象,要注意默认情况下,是不会创建的。 //聚合 n.areas = [NSMutableArray array]; TRArea *a1 = [TRArea areaWithName:@"北京" andPopulation:3000]; TRArea *a2 = [TRArea areaWithName:@"上海" andPopulation:2200]; TRArea *a3 = [TRArea areaWithName:@"广州" andPopulation:2000]; [n.areas addObject:a1]; [n.areas addObject:a2]; [n.areas addObject:a3]; for (int i = 0; i<[n.areas count]; i++) { TRArea *area = n.areas[i]; NSLog(@"name:%@ pop:%d",area.name,area.population); } } return 0; } 结果: name:北京 pop:3000 name:上海 pop:2200 name:广州 pop:2000 ====================================================================================== 知识点 九、NSSet 1.NSSet是一个无序的,管理多个对象的集合类,最大特点 是集合中不允许出现重复对象,和数学上的集合含义是一 样的。 2.除了无序、不许重复之外,其它功能和NSArray是一样的 1.NSSet的创建 TRStudent* stu1=[[TRStudent alloc]initWithAge:18 andName:@"zhangsan"]; //数值重复 TRStudent* stu2=[[TRStudent alloc]initWithAge:18 andName:@"zhangsan"]; //地址重复 TRStudent* stu3=stu1; //创建一个集合 NSSet* set=[NSSet setWithObjects:stu1,stu2,stu3, nil]; NSLog(@"%@",set); 结果: {( )} 2.hash方法(比较地址) 1.计算机默认认为对象的hash值相同,那么对象就相同、重复 2.在生活中,hash值相同的重复满足不了我们的需求,需要重写hash方法 3.hash方法重写有两种情况: 1.把返回值写死,那么该类所有的对象都可能相同 2.把对象中的其中一个属性值作为返回值,属性值相同的,对象也可能相同 3.isEqual方法(比较值) 1.如果返回值为真 确定两个对象是相同的。 2.如果返回值为假 确定两个对象是不相同的。 执行顺序,会自动先判断hash值,hash相同才会自动判断isEqual方法。 总结: a.判断引用是否是同一个, 是则可能相同 ,否一定不同 b.判断引用的类型是否相同, 是则可能相同, 否一定不同, c.判断引用的值是否相同 ,是则一定相同 ,否一定不同, TRStudent.h #import @interface TRStudent : NSObject @property(nonatomic,assign)int age; @property(nonatomic,copy)NSString*name; -(id)initWithAge:(int)age andName:(NSString*)name; +(TRStudent*)studentWithAge:(int)age andName:(NSString*)name; @end TRStudent.m #import "TRStudent.h" //hash方法 @implementation TRStudent -(NSUInteger)hash{ NSLog(@"hash方法执行了"); //return [super hash]; return 1; } //重写isEqual方法 -(BOOL)isEqual:(id)object{ NSLog(@"isEqual方法执行了"); //return [super isEqual:object]; //1.自反性 if(self == object){//两个引用指向同一个对象 return YES; }else{ //2.类型是否相同 如果类型不相同 肯定不同 if(![object isMemberOfClass:[TRStudent class]]){ return NO; }else{//3.两个对象的类型相同才比较对象的值 TRStudent *otherStu = object; if (self.age==otherStu.age&&[self.name isEqualToString:otherStu.name]) { return YES; }else{ return NO; } } } return NO; } -(id)initWithAge:(int)age andName:(NSString*)name{ self = [super init]; if (self) { self.age = age; self.name = name; } return self; } +(TRStudent*)studentWithAge:(int)age andName:(NSString*)name{ return [[TRStudent alloc]initWithAge:age andName:name]; } @end main.m #import #import "TRStudent.h" int main(int argc, const char * argv[]) { @autoreleasepool { TRStudent *stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan"]; TRStudent *stu2 = [TRStudent studentWithAge:18 andName:@"zhangsan"]; TRStudent *stu3 = stu1; NSSet *set = [NSSet setWithObjects:stu1,stu2,stu3, nil]; NSLog(@"set:%@",set); } return 0; } 结果: hash方法执行了 hash方法执行了 isEqual方法执行了 hash方法执行了 set:{( )} 知识点 十、NSMutableSet 知识点 十一、NSDictionary(不可变字典) 1.为了查找集合中的对象更快速 2.通过key(键)(名字),相应的value(值)。 通常来讲,key的值是字符串类型,value的值是任意对象类型 3.key值是不允许重复的,value的值是可以重复的 4.通来来讲key与value的值,不允许为空 1.NSDictionary的创建 //初始化的时候value->key NSDictionary* dic=[NSDictionary dictionaryWithObjectsAndKeys:@1,@"one",@2,@"two",@3,@"three", nil]; //显示的时候 key->value NSLog(@"%@",dic); 结果: { one = 1; three = 3; two = 2; } 2.通过key找到相应的value //根据key值找到相应的value NSNumber* n1=[dic objectForKey:@"one"];dic接上边的内容 NSLog(@"n1:%@",n1); //字典引用 新语法 NSNumber* n2=dic[@"one"]; NSLog(@"n2:%@",n2); 结果: n1:1 n2:1 3.获取字典中所有的value和key //集合中所有的key NSArray*key=[dic allKeys]; NSLog(@"%@",key); //集合中所有的value NSArray*v=[dic allValues]; NSLog(@"%@",v); 结果: ( one, two, three ) ( 1, 2, 3 ) 4.NSDictionary遍历 //遍历 //得到字典中所有的key NSArray* keys=[dic allKeys]; for (NSString* key in keys) { //通过每一个key得到字典中的value NSNumber* value=[dic objectForKey:key]; NSLog(@"key:%@ value:%@",key,value); } 结果: key:one value:1 key:two value:2 key:three value:3 5.NSDictionary新语法 1.创建 NSDictionary *dict = @{@"1":stu, @"2":stu1}; NSDictionary* dic=[NSDictionary dictionaryWithObjectsAndKeys:@1,@"one",@2,@"two",@3,@"three", nil]; NSDictionary* dic2=@{@"one": @1,@"two":@2,@"three":@3};//字典引用 新语法 2.获取 NSLog(@"%@", mdict[@"1"]); NSNumber* n1=[dic objectForKey:@"one"]; //字典引用 新语法 NSNumber* n2=dic[@"one"]; 6.对关键字进行排序 1.将字典中所有key值,按object所在类中的compare方法 进行排序,并将结果返回至数组,2.在Student类中添加compare方法 #import #import "TRStudent.h" int main(int argc, const char * argv[]) { @autoreleasepool { TRStudent *stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan"]; TRStudent *stu2 = [TRStudent studentWithAge:19 andName:@"lisi"]; TRStudent *stu3 = [TRStudent studentWithAge:20 andName:@"wangwu"]; TRStudent *stu4 = [TRStudent studentWithAge:21 andName:@"zhaoliu"]; NSDictionary *stus = [NSDictionary dictionaryWithObjectsAndKeys:stu1,stu1.name,stu2,stu2.name,stu3,stu3.name,stu4,stu4.name, nil]; //排序前 NSArray *allKeys = [stus allKeys]; for (NSString *key in allKeys) { //key->value TRStudent *stu = stus[key]; NSLog(@"name:%@ age:%d",stu.name,stu.age); } //排序后 ***//1.排序的第一种方式 无法对字典进行排序 只能对key进行排序 /**/ //NSArray *allKeys = [stus allKeys];取出keys值 NSArray *sortedAllKeys = [allKeys sortedArrayUsingSelector:@selector(compare:)]; for (NSString *key in sortedAllKeys) { //key->value TRStudent *stu = stus[key]; NSLog(@"name:%@ age:%d",stu.name,stu.age); } TRStudent.h -(NSComparisonResult)compare:(TRStudent*)otherStudent{ return [self.name compare:otherStudent.name]; } ***//2.字典排序方式2 需重写compare方法 如上 NSArray *sortedAllKeys2 = [stus keysSortedByValueUsingSelector:@selector(compare:)]; for (NSString *key in sortedAllKeys2) { //key->value TRStudent *stu = stus[key]; NSLog(@"name:%@ age:%d",stu.name,stu.age); } } return 0; } 7.文件操作 1.将字典内容写入文件 NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@1,@"one",@2,@"two", nil]; [dic writeToFile:@"/Users/tarena/Desktop/dic.xml" atomically:NO]; 练习 :学生和书的故事,字典方法。 (优:通过班级信息可以直接显示学生信息、通过学院信息也可以直接显示学生信息) #import #import "TRStudent.h" int main(int argc, const char * argv[]) { @autoreleasepool { //学生 TRStudent *stu1 = [TRStudent studentWithAge:18 andName:@"zhangsan"]; TRStudent *stu2 = [TRStudent studentWithAge:22 andName:@"li"]; TRStudent *stu3 = [TRStudent studentWithAge:19 andName:@"zhaoliu"]; TRStudent *stu4 = [TRStudent studentWithAge:19 andName:@"wangwu"]; TRStudent *stu5 = [TRStudent studentWithAge:20 andName:@"qianqi"]; TRStudent *stu6 = [TRStudent studentWithAge:21 andName:@"guanyu"]; TRStudent *stu7 = [TRStudent studentWithAge:20 andName:@"zhangfei"]; TRStudent *stu8 = [TRStudent studentWithAge:18 andName:@"liubei"]; //创建班级 NSArray *class1412A = [NSArray arrayWithObjects:stu1,stu2, nil]; NSArray *class1412B = [NSArray arrayWithObjects:stu3,stu4, nil]; NSArray *class1412C = [NSArray arrayWithObjects:stu5,stu6, nil]; NSArray *class1412D = [NSArray arrayWithObjects:stu7,stu8, nil]; //创建学院 NSDictionary *college3G = [NSDictionary dictionaryWithObjectsAndKeys:class1412A,@"class1412A",class1412B,@"class1412B", nil]; NSDictionary *collegeTest = [NSDictionary dictionaryWithObjectsAndKeys:class1412C,@"class1412C",class1412D,@"class1412D", nil]; //创建学校新语法 /* NSDictionary *universityTarena = [NSDictionary dictionaryWithObjectsAndKeys:college3G,@"college3G",collegeTest,@"collegeTest", nil]; */ NSDictionary *universityTarena = @{@"college3G":college3G,@"collegeTest":collegeTest}; //遍历 //学校 NSArray *collegeKeys = [universityTarena allKeys];//取出所有Keys for (NSString *collegeKey in collegeKeys) { NSDictionary *collegeValue = [universityTarena objectForKey:collegeKey]; //if... 查看某个学院的学生信息 //遍历学院 NSArray *classKeys = [collegeValue allKeys]; for (NSString *classKey in classKeys) { /* 根据班级信息 显示学生信息 if ([classKey isEqualToString:@"class1412C"]) { NSArray *classValue = [collegeValue objectForKey:classKey];直接输出,不需要遍历班级即可 } */ NSArray *classValue = [collegeValue objectForKey:classKey]; //遍历班级 for (TRStudent *stu in classValue) { /* 根据姓名查询学生信息 if ([stu.name isEqualToString:@"zhangsan"]) { NSLog(@"name:%@ age:%d",stu.name,stu.age); }*/ NSLog(@"name:%@ age:%d",stu.name,stu.age); } } } } return 0; } =================================================================================================== 知识点 十二、Block代码段 1.Block封装了段代码,可以在任何时候调用执行,Block可以作为方法的参数、方法的返回值,和传统的函数指针相似。 2.Block与函数的区别 a.Block是OC的语法 b.Block的定义可以写在方法中 c.使用起来更直接,耦合度更低 d.直接用,不用声明 3.Block的语法 a.声明 返回值类型 Block变量名 参数 int(^Sum2)(int,int) b.定义 返回值类型 参数 = ^int(int i,int j){ return i+j; }; c.调用 Block变量名 Sum2(1,2); d.自定义Block类型 Block类型 typedef void(^Block)(void); Block b1;使用类型声明变量 b1();Block变量才可以使用 1.Block的定义与声明 1.声明定义在函数外 #import //^block的标识 Sum是block的名字 //声明时也可以省略到变量i,j //通常定义与声明放到一起 int(^Sum)(int i,int j)=^(int i,int j){ return i+j; }; int main(int argc, const char * argv[]) { @autoreleasepool { int s=Sum(1,2);//block调用 NSLog(@"%d",s); } return 0; } 结果:3 2.定义在函数内部 int main(int argc, const char * argv[]) { @autoreleasepool { //block的定义与声明可以放到函数内部 int(^Sum2)(int i,int j);//声明 Sum2=^(int i,int j){//定义 return i+j; }; int s2=Sum2(3,4);//block调用 NSLog(@"%d",s2); } return 0; } 结果:7 1.Block的排序 @autoreleasepool { TRStudent* stu1=[TRStudent studentWithAge:18 andName:@"zhangsan"]; TRStudent* stu2=[TRStudent studentWithAge:23 andName:@"lisi"]; TRStudent* stu3=[TRStudent studentWithAge:22 andName:@"wangwu"]; TRStudent* stu4=[TRStudent studentWithAge:17 andName:@"fangwu"]; NSArray* array=[NSArray arrayWithObjects:stu1,stu2,stu3,stu4, nil]; NSLog(@"%@",array); NSArray* array2=[array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { TRStudent*stu11=obj1;//利用两个进行比较 TRStudent*stu21=obj2; //return [stu1.name compare:stu2.name]; NSNumber*n1=[NSNumber numberWithInt:stu11.age]; NSNumber*n2=[NSNumber numberWithInt:stu21.age]; return [n1 compare:n2]; }]; NSLog(@"%@",array2); 结果: ( "age:18 name:zhangsan", "age:23 name:lisi", "age:22 name:wangwu", "age:17 name:fangwu" ) ( "age:17 name:fangwu", "age:18 name:zhangsan", "age:22 name:wangwu", "age:23 name:lisi" ) 2.自定义Block类型 //自定义 // 返回值类型 Block是类型 参数 typedef void(^Block)(void); Block b1; b1=^{ NSLog(@"Block"); };//注意封号 b1();//调用 结果: Block 作业: 1.通讯录 TelphoneInfo name 有多个用户 添加用户信息addUser:(TRUserInfo*)… 删除用户信息->根据用户姓名removeUserByName 查看(单) 某个人信息->根据用户姓名 checkByName 查看(多) 所有人信息 list… 查看(多) 所有人信息->根据用户姓名排序 sortedListByName… 用户 UserInfo name email telphone show 显示用户信息 TRUserInfo.h #import @interface TRUserInfo : NSObject @property(nonatomic,copy)NSString *name; @property(nonatomic,copy)NSString *telphone; @property(nonatomic,copy)NSString *email; -(id)initWithName:(NSString *)name andTelphone:(NSString *)telphone andEmail:(NSString *)email; +(TRUserInfo*)userInfoWithName:(NSString *)name andTelphone:(NSString *)telphone andEmail:(NSString *)email; -(void)show; @end TRUserInfo.m #import "TRUserInfo.h" @implementation TRUserInfo -(id)initWithName:(NSString *)name andTelphone:(NSString *)telphone andEmail:(NSString *)email{ self = [super init]; if (self) { self.name = name; self.telphone = telphone; self.email = email; } return self; } +(TRUserInfo*)userInfoWithName:(NSString *)name andTelphone:(NSString *)telphone andEmail:(NSString *)email{ return [[TRUserInfo alloc]initWithName:name andTelphone:telphone andEmail:email]; } -(void)show{ NSLog(@"name:%@ telphone:%@ email:%@",self.name,self.telphone,self.email); } @end TRTelphoneInfo.h #import #import "TRUserInfo.h" @interface TRTelphoneInfo : NSObject @property(nonatomic,copy)NSString *name; -(id)initWithName:(NSString*)name; +(id)telphoneInfoWithName:(NSString*)name; //添加用户信息 -(void)addUser:(TRUserInfo*)user; //删除用户信息 -(void)removeUserByName:(NSString*)name; //查看某个人信息 -(void)checkUserByName:(NSString*)name; //查看所有人信息 -(void)list; //查看所有人信息并排序 -(void)sortedListByName; @end TRTelphoneInfo.m #import "TRTelphoneInfo.h" //扩展方法 组合 @interface TRTelphoneInfo() @property(nonatomic,strong)NSMutableArray *userInfos; @end @implementation TRTelphoneInfo -(id)initWithName:(NSString*)name{ self = [super init]; if (self) { self.name = name; self.userInfos = [NSMutableArray array]; } return self; } +(id)telphoneInfoWithName:(NSString*)name{ return [[TRTelphoneInfo alloc]initWithName:name]; } //添加用户信息 -(void)addUser:(TRUserInfo*)user{ [self.userInfos addObject:user]; } //删除用户信息 -(void)removeUserByName:(NSString*)name{ TRUserInfo *temp = nil; for (TRUserInfo* userInfo in self.userInfos) { if([userInfo.name isEqualToString:name]){ temp = userInfo; } } [self.userInfos removeObject:temp]; } //查看某个人信息 -(void)checkUserByName:(NSString*)name{ BOOL isFlag = NO; for (TRUserInfo* userInfo in self.userInfos) { if([userInfo.name isEqualToString:name]){ //NSLog(@"name:%@ telphone:%@ email:%@",userInfo.name,userInfo.telphone,userInfo.email); isFlag = YES; [userInfo show]; break; } } if (!isFlag) { NSLog(@"您输入的姓名不存在,请重新输入!"); } } //查看所有人信息 -(void)list{ for (TRUserInfo* userInfo in self.userInfos) { [userInfo show]; } } //查看所有人信息并排序 -(void)sortedListByName{ NSArray *sortedUserInfos = [self.userInfos sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { TRUserInfo *stu1 = obj1; TRUserInfo *stu2 = obj2; return [stu1.name compare:stu2.name]; }]; for (TRUserInfo* userInfo in sortedUserInfos) { [userInfo show]; } } @end main.m #import #import "TRUserInfo.h" #import "TRTelphoneInfo.h" int main(int argc, const char * argv[]) { @autoreleasepool { TRUserInfo *u1 = [TRUserInfo userInfoWithName:@"zhangsan" andTelphone:@"13700000000" andEmail:@"[email protected]"]; TRUserInfo *u2 = [TRUserInfo userInfoWithName:@"lisi" andTelphone:@"13800000000" andEmail:@"[email protected]"]; TRUserInfo *u3 = [TRUserInfo userInfoWithName:@"wangwu" andTelphone:@"13900000000" andEmail:@"[email protected]"]; TRTelphoneInfo *telphoneInfo = [TRTelphoneInfo telphoneInfoWithName:@"电信"]; //添加用户信息 [telphoneInfo addUser:u1]; [telphoneInfo addUser:u2]; [telphoneInfo addUser:u3]; //查看所有用户信息 //[telphoneInfo list]; //查看按姓名排序的所有用户信息 //[telphoneInfo sortedListByName]; //查看某个人的信息 通过名字 //[telphoneInfo checkUserByName:@"lisi"]; //根据姓名 删除某个人的信息 [telphoneInfo removeUserByName:@"lisi"]; [telphoneInfo list]; } return 0; } 作业2: 学生管理系统 1.创建班级 2.删除班级 3.查询所有班级 4.向班级中添加学生 5.查询所有班级所有学生 6.删除班级中的学生 7.学生有学习成绩(语文、数学、英语) 8.将学生的成绩排序 补充: 1.Runtime是什么 1.是OC语言提供的一些C函数库,这些C函数可以在程序运行期间获取类信息,创建对象,调用方法。。。 2.当通过Selector调用方法时,编译器无法确认内存中是否有问题,会有相应警告出现,可以用以下方式取消警告。 3.OC真在在执行的时候,会先翻译成C++/C,再转换成汇编代码(计算机识别的代码)。OC非真正面向对象,而是假的面向对象。 2.NSObjectRuntime.h头文件串的函数 NSStringFromSelector //根据方法获取方法名 NSSelectorFromString //根据方法名获取方法 NSStringFromClass //根据类获取类名 NSClassFromString //根据类名获取类 NSStringFromProtocol //根据协议获取协议名 NSProtocolFromString //根据协议名获取协议 NSDictionary *user = @{@"className":@"TRPerson", @"property":@{@"name":@"zhangsan",@"gender":@"female"}, @"method":@"show"}; NSDictionary *user2 = @{@"className":@"TRPerson", @"property":@{@"name”:@“lisi”,@“gender”:@“Male”}, @"method":@"show"}; NSArray *users = @[user,user2]; 例: @autoreleasepool { //通过字符串信息,也可以创建对象 NSString *className = @"TRPerson"; Class class = NSClassFromString(className); id obj = [[class alloc]init]; NSString *methodName = @"show"; SEL method = NSSelectorFromString(methodName); [obj performSelector:method]; NSString *name = @"zhangsan"; NSString *gender = @"male"; SEL setName = NSSelectorFromString(@"setName:"); [obj performSelector:setName withObject:name]; SEL setGenger = NSSelectorFromString(@"setGender:"); [obj performSelector:setGenger withObject:gender]; [obj performSelector:method]; //模拟动态创建对象,可以叫反射 //根据文件中读出来的数据 创建相应的对象 NSDictionary *user = @{@"className":@"TRPerson", @"property":@{@"name":@"zhangsan",@"gender":@"female"},@"method":@"show"}; NSArray *users = @[user,user2]; for (NSDictionary *user in users) { //通过运行时 得到对象 属性 方法 //创建一个对象 ***放到对象数组中 } } copy:得到一个不可改变的对象,复制了一份。NSstring strong:只得到一个内存空间 NSMutableString ARC: NSstring 、block:copy OC对象:strong 简单基本数据类型、结构体: assign