一、NSString是1个类,定义在Foundation框架中,NSString对象的作用:用来存储字符串数据的。
既然是1个类,那么标准的创建NSSting对象的方式有如下几种:
NSString *str1 = [NSString new]; NSString *str2 = [[NSString alloc] init]; NSString *str3 = [NSString string];
以这样的方式创建的字符串对象中存储的字符串数据是@“” 是一个空字符串,注意不是“ ”(空格)。
由于NSString 是OC中常用的对象,所以为了快速的创建NSString对象,可以使用@符号
NSString * name = @"jack";
@"jack"这是1种创建字符串对象的简写的方式,实际上是创建了1个字符串对象,将jack存储进去,name中实际存储的是这个对象的地址。
使用%p打印指针变量的值,使用%@打印指针指向的对象,调用对象的description方法。(注意这个方法是从NSObject类中继承的,在NSString子类重写了的)。
二、谈谈NSString的恒定性
1.当我们创建字符串对象的时候,如果使用@符合来创建的,那么这个字符串对象是存储在常量区(或叫全局区)的。
如果调用方法来创建字符串对象,那么对象是存储在堆区的。
NSString *str1 = @"jack"; //这个字符串对象存储在常量区的 NSString *str2 = [NSString new]; //这个字符串对象是存储在堆区的. NSLog(@"str1 = %p",str1); NSLog(@"str2 = %p",str2);
结构你会发现这两个地址相差很大很大,足以证明不在同一个区的。
2.存储在内存中的字符,无论是在堆区还是在常量区都是不可以改变的,这个就是NSString的恒定性,也就是不可变性。
字符串对象一旦创建,这个字符串对象中存储的字符串数据就不能改变,永远只能存储这个。
我们为NSString指针重新赋值1个字符串的时候,不是修改原来的字符串,而是重新创建了1个字符对象,将这个字符串的地址赋值给指针。不可更改性,也就是针对堆区和常量区的对象说的。
NSString * name = @"jack"; name = @"rose";//在常量区重新开辟了一个空间存储rose对象,并把rose对象的地址赋值给name指针,而jack对象仍然存在内存中,未被他人修改
3.当系统准备在内存中创建1个字符串对象的时候。比如:准备为常量区创建字符对象的时候,先检查常量区有没有内容相同的字符串对象,如果有,就让指针直接指向(所以就存在多个指针指向同一个对象的说法了),如果没有才会创建。
那么堆区呢?同样的道理,如果字符串创建在堆区,是不会去常量区检查的,只会在堆区查找有没有相同的内容的字符串,如果有就直接指向,如果没有才会重新创建。
4.常量区的数据是不会被回收的,所以创建在常量区的字符串是不会被回收的,直到程序结束。那为什么不允许被回收呢,原因就是为了提高效率。你看,当字符串第二次使用的时候,就不要重新创建字符串了,直接使用。
三、NSSting类的常用方法。
1.得到字符串的长度。
@property (readonly) NSUInteger length;
2.得到指定下标的字符。
- (unichar)characterAtIndex:(NSUInteger)index; 返回值是unichar 打印unichar使用%C
3.拼接变量的方式组成1个新的字符串。是一个类方法
+ (instancetype)stringWithFormat:(NSString *)format, ...
实例: NSString *str = [NSString stringWithFormat:@"大家好,我叫%@,我今年%d岁",name,age];
4.将C语言的字符串转换为OC语言的字符串
将C语言的字符串转换为OC字符串对象. + (nullable instancetype)stringWithUTF8String:(const char *)nullTerminatedCString; nullable: 代表返回的对象有可能是nil
char *name = "杰克"; NSString *str = [NSString stringWithUTF8String:name]; NSLog(@"str = %@",str);
5.判断两个字符串的内容是否相同。如果要判断两个字符串的内容是否相同,不要使用==来判断而是使用对象方法,这个方法NSString类已经提供了。注意从第一个字符开始比ASCII码。
- (NSComparisonResult)compare:(NSString *)string; 返回的是1个枚举值. NSOrderedAscending : 当前字符串比传入的字符串小. NSOrderedSame: 一样 NSOrderedDescending 当前字符串比传入的字符串大
NSComparisonResult res = [str1 compare:str2]; switch (res) { case NSOrderedAscending: NSLog(@"小了"); break; case NSOrderedSame: NSLog(@"一样"); break; case NSOrderedDescending: NSLog(@"大了"); break; }
指定选项的比较. 1). 忽略大小写的比较. NSString *str1 = @"jack"; NSString *str2 = @"JACK"; int len = [str1 compare:str2 options:NSCaseInsensitiveSearch]; 2). 完全匹配的比较. NSString *str1 = @"jack"; NSString *str2 = @"JACK"; int len = [str1 compare:str2 options: NSLiteralSearch]; 3). 比较字符串中的数字的大小. NSString *str1 = @"img100021.jpg"; NSString *str2 = @"img100012.jpg"; int len = [str1 compare:str2 options: NSNumericSearch]; 比较的是字符串中数组的大小. 使用前提: 两个字符串的格式要相同.一般情况下用来比较两个路径
6.只判断两个字符串是否相同,返回值是BOOL类型的,只是看内容是否一模一样,相同就是YES,否则NO
- (BOOL)isEqualToString:(NSString *)aString;
NSString *str1 = @"jack"; NSString *str2 = @"jack"; BOOL res = [str1 isEqualToString:str2]; NSLog(@"res = %d",res);
7.将OC字符串转换为C字符串。
@property (nullable, readonly) __strong const char *UTF8String
NSString *str = @"jack"; const char * ch = [str UTF8String]; printf("%s\n", ch);
8.大小写转换
// 所有字符转换成大写 @property (readonly, copy) NSString *uppercaseString; // 所有字符转换成小写 @property (readonly, copy) NSString *lowercaseString; // 每个单词首字母大写,其余字母小写。 @property (readonly, copy) NSString *capitalizedString;
9.将字符串写到指定的文件中去
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)error;
实例:
NSError *err = nil; //NSError对象. BOOL res = [str writeToFile:@"/aaUsers/Itcast/Desktop/abc.txt" atomically: NO encoding:NSUTF8StringEncoding error:&err]; if(err == nil) { NSLog(@"ok"); } else { NSLog(@"no ok"); NSLog(@"%@",err.localizedDescription);//可以得到错误信息 }
10.从指定的字符中读取字符串数据
+ (nullable instancetype)stringWithContentsOfFile:(NSString *)path encoding:(NSStringEncoding)enc error:(NSError **)error;
NSError *err = nil; NSString *str = [NSString stringWithContentsOfFile:@"/Users/Desktop/abc.txt" encoding:NSUTF8StringEncoding error:nil]; //str的值如果是nil 说明失败. //err的值如果不是nil 说明失败. NSLog(@"%@",str);
字符串对象不仅可以从磁盘上读取文件的内容. 还可以从网络上读写数据. 可以读取1个网页的源代码.ftp服务器上的文件也可以读取. 网页地址,ftp文件地址. URL 统一资源路径. 也就是1个网址.ftp文件的地址. 磁盘上的文件的地址. 网址的URL标准写法: http://www.baidu.com ftp文件的URL标准写法: ftp://server.sina.com/aa.avi 磁盘文件路径: file:///Users/Desktop/abc.txt NSString可以从1个URL路径中读写数据. 1). 先将URL路径封装在1个NSURL对象中 NSURL *url1 = [NSURL URLWithString:@"http://www.itheima.com"]; NSURL *url2 = [NSURL URLWithString:@"ftp://server.itheima.com/1.txt"]; NSURL *url3 = [NSURL URLWithString:@"file:///Users/Itcast/Desktop/abc.txt"]; 2). 使用类方法从NSURL对象中读取数据. + (nullable instancetype)stringWithContentsOfURL:(NSURL *)url encoding:(NSStringEncoding)enc error:(NSError **)error; 3). 往NSURL中写入数据. - (BOOL)writeToURL:(NSURL *)url atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)error;
11.判断字符串是否以指定的字符串开始的
- (BOOL)hasPrefix:(NSString *)str;
12.判断字符是否以自定的字符串结束的
- (BOOL)hasSuffix:(NSString *)str;
13.在字符串中搜索子字符串的范围
@“I love rose”;
@"love"
范围:起始下标是2:长度是:4
- (NSRange)rangeOfString:(NSString *)searchString
返回值代表子字符串在主串中的范围。返回值是一个NSRange 这是一个结构体
typedef struct _NSRange { NSUInteger location; NSUInteger length; } NSRange;
location:代表了这段范围的起始下标
length:代表匹配的长度
如果在主串中没有找到子串,返回的NSRange结构体变量的length值是0,location的值就是NSUInteger的最大值。
如果找到的情况下:
location的值就是第一次匹配的下标
length:代表子串的长度
- (void)appendString:(NSString *)aString; 以拼接的方式追加. - (void)appendFormat:(NSString *)format, ...
说明一下:Range是Foundation框架中定义的一个结构体
这个结构体变量用来表示1个范围的,一般情况下,用来表示子串在主串中的范围
location:起始下标
length:匹配到的长度
@“我爱你北京”
@“爱你”
location:1
length:2
NSRange结构体变量的初始化
a.最简单的初始化,先声明结构体变量,再初始化属性
NSRange range;
range.location = 2;
range.length = 3;
b.NSRange = {2, 3};
c.NSRange range = {.location = 2, .length = 3};
d.Foundation框架提供了1个函数来快速创建1个NSRange结构体变量。
NSRange range = NSMakeRange(2,3);
e.将NSRange结构体变量转换为字符串
NSRange range = NSMakeRange(2,3);
NSString * str = NSStringFromRange(range);
NSLog(@"%@",str);
14.字符串的截取
从指定的下标开始一直截取到最后 - (NSString *)substringFromIndex:(NSUInteger)from; 截取前面指定个数的字符串. - (NSString *)substringToIndex:(NSUInteger)to; 截取指定的范围的字符串. - (NSString *)substringWithRange:(NSRange)range;
15.字符串的替换
@"我很爱很爱你"; 将字符串中的 爱 换成 恨 - (NSString *)stringByReplacingOccurrencesOfString:(NSString *)target withString:(NSString *)replacement 注意的是: 各种操作字符串的方法.原来字符串本身不会变.因为字符串的恒定性. 最终的操作结果都是以返回值返回来的. 还可以实现删除的效果: 将指定的字符串换成@""
16.删除子串前后空格
NSString *str = @" chiwcniwnciwe c winciwn ciewnciewc fcneivbcnei "; str = [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 只能删除前后的空格,中间的空格如果要删除就是以替换.
四、NSMutableString
1.是Foundation框架中的1个类,从NSString继承,NSString所拥有的功能,NSMutableString都有。
只是对NSString进行了扩展,存储在NSMutableString对象中的字符串数据具备可变性,存储在其中的字符串数据可以改。
NSMutableString字符串的创建方法:
NSMutableString *str1 = [NSMutableString new]; NSMutableString *str2 = [[NSMutableString alloc] init]; NSMutableString *str3 = [NSMutableString string];
2.注意:NSMutableString *str1 = @“jack”;这样的写法是错误的,因为@“jack”是一个NSString对象,str1是1个类指针。如果通过这个指针调用子类独有的方法的时候,运行就会运行报错。
3.如何往NSMutableString对象中存储字符串数据
将字符串追加存储到NSMutableString对象中
- (void)appendString:(NSString *)aString; 以拼接的方式追加. - (void)appendFormat:(NSString *)format, ...
NSMutableString *str = [NSMutableString string]; [str appendString:@"jack"]; [str appendString:@"jack"]; [str appendString:@"jack"]; int num = 19; [str appendFormat:@"haha%dhaha",num]; NSLog(@"%@",str);
注意:NSMutableString对象追加数据,直接就是改的这个对象的内容,不会创建新的对象
4.使用NSMutableString做大量字符串拼接效率就很高了。为什么?因为NSMutableString对象始终只有一个,每次拼接的时候都是直接修改这个对象,并没有创建新的对象。
5.什么时候使用?
NSString:不拼接的时候,同一个字符串对象,如果后面要使用,就不会再创建了,但是大量拼接效率低。
NSMutableString:只有alloc new 都是1个新对象,优点:大量拼接的时候效率高。拼接次数超过7次就认为是大量拼接。
6.将可变字符串对象转换为不可变字符串对象,
调用可变字符串对象的copy(后面详讲)方法,就返回1个NSString对象。