学习目标
1.【理解】NSString
2.【了解】NSString的常用方法
3.【了解】NSRange
4.【了解】NSMutableString
5.【掌握】NSArray
6.【了解】NSArray的常用方法
7.【掌握】遍历数组的三种方式
8.【了解】NSArray与字符串
9.【掌握】NSMutableArray
一、NSString
在OC中,使用NSString类型的对象来保存一个字符串对象的地址,OC字符串必须要使用 @ 前缀。NSString其实是Foundation框架中的一个类,字符串以NSString对象的形式保存。如果是以字符串常量去初始化一个NSString指针,那么这个字符串常量是存储在常量区之中的。如果是以调用NSString的类方法来得到一个字符串对象,这个对象就创建在堆区。并且一旦在内存中(无论堆区、常量区)创建了一个字符串对象,这个字符串对象的字符内容就无法修改。
//OC字符串常量需要加@,并且这种方式创建的字符串存储在常量区,不需要自己释放内存 NSString *str1 = @"OC字符串";//常量区 //C语言的字符串转换为OC字符串 NSString *str2 = [[NSString alloc] initWithUTF8String:"C字符串"]; const char *strc = str2.UTF8String;//将OC字符串转为C语言字符串 NSUInteger length = str2.length;//计算字符串长度 //类方法格式化创建一个字符串对象 NSString *str3 = [NSString stringWithFormat:@"格式"];//堆区 //构造方法创建字符串对象 NSString *str4 = [[NSString alloc] initWithString:@"OC字符串"];//常量区 //对象方法格式化创建字符串对象 NSString *str5 = [[NSString alloc] initWithFormat:@"拼接字符串%@",str4];//堆区
二、NSString的常用方法
从文件中读取或写入字符串
//创建一个字符串常量 NSString *str1 = @"我爱北京天安门"; /* 将字符串写入文件 writeToFile: 参数为将存储字符串的文件路径 atomically: 参数为YES(安全,低效) NO(不安全,高效) encoding: 参数为字符编码,一般为NSUTF8StringEncoding error: 参数为NSError类型的二级指针,可以传nil不接受错误信息 返回值是BOOL类型,如果成功返回YES */ NSError *err = nil; //将str1写入到指定文件并接收是否写入成功 BOOL b = [str1 writeToFile:@"/Users/itcast/Desktop/text.txt" atomically:NO encoding:NSUTF8StringEncoding error:&err]; //判断是否写入成功,失败则输出错误信息 if (err == nil) { NSLog(@"写入成功"); }else { NSLog(@"%@",[err localizedDescription]); } //调用类方法创建NSURL对象,存储url(统一资源定位符) NSURL *url = [NSURL URLWithString:@"file:///Users/itcast/Desktop/text.txt"]; //将url里的字符串存储到str NSString *str3 = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil]; //存储资源的文件 NSURL *url1 = [NSURL fileURLWithPath:@"/Users/itcast/Desktop/text1.txt"]; //将字符串写入文件 [str3 writeToURL:url1 atomically:YES encoding:NSUTF8StringEncoding error:nil]; //从文件读取字符串存储到字符串 NSString *str2 = [NSString stringWithContentsOfFile:@"/Users/itcast/Desktop/text.txt" encoding:NSUTF8StringEncoding error:nil]; /* 一般写入字符串到文件的方法返回值类型都是BOOL,如果返回YES则表示写入成功,返回NO表示写入失败,并且我们可以使用NSError类对象来接受失败错误信息。 */
字符串的比较和判断
//比较两个字符串的大小 //NSComparisonResult的定义 //typedef NS_ENUM(NSInteger, NSComparisonResult) { // NSOrderedAscending = -1L,//第一个小于第二个 // NSOrderedSame,//两个字符串内容相等 // NSOrderedDescending//第一个大于第二个 //}; NSString *str1 = @"abc"; NSString *str2 = @"Abc"; //是比较两个字符串的字符的ASCII码大小 NSComparisonResult res = [str1 compare:str2]; NSLog(@"res = %ld",res);//res = 1 //忽略大小写比较 NSComparisonResult res1 = [str1 compare:str2 options:NSCaseInsensitiveSearch]; NSLog(@"res1 = %ld",res1);//res = 0 //判断两个字符串是否相等 BOOL res2 = [str1 isEqualToString:str2]; NSLog(@"res = %d",res2);//res = 0 //判断字符串的前缀、后缀 NSString *str = @"/User/itcast/Desktop/xx.mp3"; //判断字符串是否以 http:// 开头 BOOL res3 = [str hasPrefix:@"http://"]; //判断字符串是否以 .mp3 结尾 BOOL res4 = [str hasSuffix:@".mp3"]; //在字符串中搜索子串第一次出现的范围 NSString *str3 = @"我爱你广州小蛮腰,广州爱我的钞票"; NSRange res5 = [str rangeOfString:@"广州"]; //输出子串起始下标和长度 NSLog(@"location = %ld length = %ld",res5.location,res5.length);//location = 3 length = 2 //在字符串中搜索子串最后一次出现的范围 NSRange res6 = [str rangeOfString:@"广州" options:NSBackwardsSearch]; //输出子串最后一次出现的下标和长度 NSLog(@"location = %ld length = %ld",res6.location,res6.length);//location = 9 length = 2
字符串的截取,从一个字符串中,取出一个子字符串来
NSString *str = @"jackloverose"; //取出指定单个字符 unichar ch = [str characterAtIndex:0]; NSLog(@"ch = %C",ch);//ch = j //从字符中指定的下标截取到最后 NSString *newStr1 = [str substringFromIndex:4]; NSLog(@"newStr1 = %@",newStr1);//newStr = loverose //从第0个元素截取到指定的下标 NSString *newStr2 = [str substringToIndex:4]; NSLog(@"newStr2 = %@",newStr2);//newStr = jack //从字符串中截取一个范围的子字符串 NSString *newStr3 = [str substringWithRange:NSMakeRange(4, 4)]; NSLog(@"newStr3 = %@",newStr3);//newStr = love
字符串的替换,将字符串中符合要求的子串替换成另外的字符串
NSString *str = @"admin#6ag.cn"; //将str字符串的所有的@"#"替换为@"@",产生新的字符串,不会修改原先字符串 NSString *newStr = [str stringByReplacingOccurrencesOfString:@"#" withString:@"@"]; NSLog(@"%@",newStr);//admin@6ag.cn
将字符串转为一些基本数据类型
@property (readonly) double doubleValue; @property (readonly) float floatValue; @property (readonly) int intValue; @property (readonly) NSInteger integerValue NS_AVAILABLE(10_5, 2_0); @property (readonly) long long longLongValue NS_AVAILABLE(10_5, 2_0); @property (readonly) BOOL boolValue NS_AVAILABLE(10_5, 2_0); //例如将字符串转为int类型再相加 NSString *str1 = @"100fdf"; //当字符串字面量不是纯数字,能转多少是多少。这里忽略数字后的字面 NSString *str2 = @"200a"; //属性可以直接用点语法调用 int result = str1.intValue + str2.intValue; NSLog(@"result = %d",result);// result = 300
C语言字符串和OC字符串互转
//C语言的字符串转换为OC字符串 NSString *str2 = [NSString stringWithUTF8String:"C字符串"]; //将OC字符串转为C语言字符串 const char *strc = str2.UTF8String; NSUInteger length = str2.length;//计算字符串长度
三、NSRange
NSRange是Foundation框架中比较常用的结构体,一个NSRange结构体变量表示一段范围。通常情况下,用来表示一个子字符串在主字符串中的范围。它的定义如下:
typedef struct _NSRange { //NSUInteger是unsigned long NSUInteger location;//表示这个范围的起始位置下标 NSUInteger length;//表示该范围内的长度 } NSRange; //第一种创建方法 NSRange range1; range1.location = 7; range1.length = 3; //第二种创建方法 NSRange range2 = {7,3}; //第三种创建方法 NSRange range3 = {.location = 7,.length = 3}; //第四种创建方法,使用函数创建,推荐使用此方法 NSRange range4 = NSMakeRange(7, 3); //最笨的输出方法 NSLog(@"{%lu, %lu}",range1.location,range1.length);// {7, 3} //使用框架提供的函数以字符串形式输出 NSLog(@"%@",NSStringFromRange(range1));// {7, 3}
四、NSMutableString
NSString字符串的特点是恒定性,一旦创建字符串对象在内存之中,这个字符串对象的内容就无法更改。当我们重新为一个 NSString指针变量赋值一个字符串的时候,会先在常量区查找是否有相同内容的字符串,如果有就直接指向,如果没有才会创建字符串。那么这样就会有一个问题,当我们做大批量的字符串拼接的时候,就会特别的消耗性能和时间。
NSString的硬伤
NSString *str = @""; for (int i = 0; i < 100000; i++) { str = [str stringByAppendingString:[NSString stringWithFormat:@"%d",i]]; } //亲测,跑了一分多钟才输出横线,可想而知手机得多卡 NSLog(@"-----------------");
Foundation提供了一个NSString的子类NSMutableString,NSMutableString对NSString做的最大的扩展就是,NSMutableString对象用来存储字符串的时候,这个对象中存储的字符串内容是可以更改的。这样在我们做字符串拼接的时候,就不会产生一个又一个的字符串对象,而是直接修改这个NSMutableString对象了。
NSMutableString *str = [NSMutableString string]; //追加字符串,不会新创建对象 [str appendString:@"jack"]; //以格式控制符的格式拼接追加字符串 [str appendFormat:@"%d",1]; NSLog(@"%@",str);//jackrose //将NSMutableString字符串转为NSString字符串 NSString *str1 = [NSString stringWithString:str];
解决NSString的硬伤
NSMutableString *str = [NSMutableString string]; for (int i = 0; i < 100000; i++) { [str appendFormat:@"%d",i]; } //刷一下就出来了,因为对象只有一个,每次拼接都是修改同一个对象 NSLog(@"-----------------");
总结:
平时我们使用字符串的时候还是尽量使用NSString,因为NSString的恒定性,当我们同一个字符串多次使用的时候,效率就很高。当我们做大批量拼接字符串的时候才用NSMutableString。
五、NSArray
C语言中的数组特点:
元素的类型一致,创建一个C语言的数组,这个数组中可以存储的数据的元素的类型必须是一致的。C语言数组的长度是固定的,一旦创建数组,就无法改变。C语言数组的元素无法删除、新增。OC中新增了数组类NSArray,在C语言的数组的基础之上做了很大的增强。
NSArray数组的特点:
1.只能存储OC对象,而且是可以存储任意OC对象。
2.这些对象在NSArray数组中是有序存放,一个挨一个的存储。
3.NSArray数组只能存储OC对象,不能存储非OC对象。所以基本数据类型等非OC对象类型无法存储。
4.NSArray数组是不可变的,一旦初始化完毕之后,它里面的元素就永远是固定的,无法删除和新增元素。
//创建一个长度为0的数组,而且无法修改 NSArray *arr1 = [NSArray array]; //创建一个长度为1的数组 NSArray *arr2 = [NSArray arrayWithObject:@"1"]; //创建一个长度为2的数组,以nil作为结束符,一定不能省略 NSArray *arr3 = [NSArray arrayWithObjects:@"1",@"2",nil,@"3",nil]; //快速创建数组的方法,不能存nil NSArray *arr4 = @[@"jack",@"rose",@"lucy"]; NSLog(@"\n%@",arr4); /* 输出 ( jack, rose, lucy ) */
六、NSArray的常用方法
NSArray *arr = @[@"jack",@"rose",@"mark"]; //取出数组元素的两种方式 NSLog(@"%@",arr[0]);//jack NSLog(@"%@",[arr objectAtIndex:0]);//jack //得到NSArray数组的长度 NSUInteger count = arr.count; NSLog(@"count = %lu",count);//count = 3 //取出元素并存储到对应对象中 NSString *str = [arr objectAtIndex:0]; NSLog(@"str = %@",str);//str = jack //判断数组中是否包含指定元素 BOOL res = [arr containsObject:@"rose"]; NSLog(@"res = %d",res);//res = 1 //取出第一个元素 NSString *str1 = arr.firstObject; NSLog(@"str1 = %@",str1);//str1 = jack //取出最后一个元素 NSString *str2 = arr.lastObject; NSLog(@"str2 = %@",str2);//str2 = mark //查找指定的元素在数组中第一次出现的下标,找不到返回NSNotFound NSUInteger index = [arr indexOfObject:@"rose"]; NSLog(@"index = %lu",index);//index = 1
七、遍历数组的三种方式
第一种,遍历数组,使用常规for循环
for (int i = 0; i < arr.count; i++) { NSLog(@"%@",arr[i]/*或 [arr objectAtIndex:i]*/); }
第二种,遍历数组,使用增强for循环
for (NSString *obj in arr){ //obj 叫 迭代变量 NSLog(@"%@",obj); } /* 增强for循环遍历NSArray数组的原理: 将NSArray数组中的每 1 个元素从头到尾的赋值给迭代变量,并执行循环体。 当将最后1个元素赋值给迭代变量并执行完循环体后,就自动结束循环。 将第 0 个元素赋值给迭代变量,执行循环体。 将第 1 个元素赋值给迭代变量,执行循环体。 将第 2 个元素赋值给迭代变量,执行循环体。 ......! 将最后 1 个元素赋值给迭代变量,执行循环体。 结束增强 for 循环。 增强 for 循环使用注意: 迭代变量的类型要和数组的元素的类型一致,否则在执行的时候如果类型不一致,会出现操作错误。 如果数组中的元素的类型不一致,就使用 id 万能指针。 增强 for 循环,遍历出来的迭代变量直接就是数组的元素的值,不是下标。 */
第三种,遍历数组,使用block
[arr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { //obj:代表遍历出来的元素的值 //idx:代表遍历出来的元素下标 //如果希望停止遍历,就给stop指针指向的变量赋值为NO NSLog(@"idx = %lu obj = %@",idx,obj); //当遍历到下标为2的元素,就停止循环 if (idx == 1) { *stop = YES; } }];
八、NSArray与字符串
//将NSArray数组中的元素链接成一个字符串 NSArray *arr = @[@"jack",@"rose",@"mark"]; //将每个元素以 # 号拼接 NSString *str = [arr componentsJoinedByString:@"#"]; NSLog(@"%@",str);//jack#rose#mark //将字符串以某个字符为分隔符存入NSArray数组 NSString *str = @"中国,广州,天河区,棠东"; //以 , 为分隔符存入数组 NSArray *arr = [str componentsSeparatedByString:@","]; //遍历输出数组 for (NSString *obj in arr) { NSLog(@"%@",obj); } /* 输出 中国 广州 天河区 棠东 */
九、NSMutableArray
NSMutableArray是NSArray的子类,所以他具备NSArray的所有特点。唯一区别就是NSMutableArray是一个可变数组,存储在该数组中的元素可以删除,可以动态的新增元素。
//初始化NSMutableArray数组 //创建一个没有任何元素的数组,最常用也是这种,因为可变数组可以新增 NSMutableArray *arr1 = [NSMutableArray array]; NSMutableArray *arr2 = [[NSMutableArray alloc] init]; //创建一个有5个元素的数组 NSMutableArray *arr3 = [[NSMutableArray alloc] initWithCapacity:5]; //创建数组的同时调用 类方法 初始化数组的元素 NSMutableArray *arr4 = [NSMutableArray arrayWithObjects:@"哈哈", @"呵呵",nil]; //创建数组的同时调用 对象方法 初始化数组的元素 NSMutableArray *arr5 = [[NSMutableArray alloc] initWithObjects:@"哈哈", @"呵呵",nil]; //NSMutableArray增删改查 //新增元素 [arr1 addObject:@"jack"]; [arr1 addObject:@"rose"]; [arr2 addObject:@"mark"]; [arr2 addObject:@"juli"]; //将arr2添加到arr1数组尾部 [arr1 addObjectsFromArray:arr2]; //在指定位置处插入元素 [arr1 insertObject:@"charu" atIndex:0]; //删除指定下标元素 [arr1 removeObjectAtIndex:1]; //删除指定值的元素 [arr1 removeObject:@"mark"]; //删除指定范围内的指定元素 [arr1 removeObject:@"jack" inRange:NSMakeRange(0, 2)]; //删除最后一个元素 [arr1 removeLastObject]; //删除所有元素 [arr1 removeAllObjects];