1. Objective+C 中的字符串
在 OC 中,我们使用 NSString 类型的指针来保存 1 个字符串对象的地址.
OC 中的字符串我们使用 1 个@前缀来表示.
NSString 其实是 Foundation 框架中的 1 个类.字符串以 NSString 对象的形式保存.
2. 如何初始化NSString
1). 直接为 NSString 指针变量初始化 1 个 OC 字符串常量.
NSString *str = @"jack";
2). 使用 new、或者 alloc 来创建 1 个空的字符串对象. @"".
NSString *str = [NSString new];
NSString *str = [[NSString alloc] init]; 这两种创建字符串对象的方式. 创建出来的字符串是@"". 空的字符串.
3). 调用 NSString 的类方法来快速得到 1 个字符串对象.
a). 得到 1 个空的字符串对象. @""
NSString *str = [NSString string];
b). 使用格式控制字符串拼接 1 个新的字符串对象.
NSString *str = [NSString stringWithFormat:@"字符串数据使用格式控制符",变量列表];
3.字符串的恒定性.
1).字符串对象的存储.
如果是以字符串常量去初始化 1 个 NSString 指针. 那么这个字符串常量是存储在常量区之中的. 如果是以调用 NSString 的类方法来得到 1 个字符串对象,这个对象就创建在堆区.
2). 一旦在内存中创建 1 个字符串对象,这个字符串对象就具备恒定性.就是这个字符串的内容无法更改.
当我们重新为这个 NSString 指针赋值 1 个字符串数据的时候,是重新创建了 1 个字符串对象,将这个对象的地 址赋值给这个指针.当需要在常量区存储 1 个字符串常量数据的时候,系统会先检查常量区中是否有相同内容的字符 串 常量.如果有,直接指向,如果没有才会重新创建.
3). 需要注意的是.如果是通过 NSString 的类方法来创建 1 个字符串对象. 这个字符串对象,无论如何是存储在堆区的
NSString *str = NSString stringWithFormat:@"jacklove%@",@"rose"]; //这个字符串对象是存储在堆区的. str = @"lilei";//为 str 重新赋值.不会改变上面的字符串对象.上面的字符串对象不会发生变化. 而是.先查看常量区中是否有@"lilei"这个字符串,如果有直接将其地址赋值给 str 如果没有才重新创建.
4.NSString常用方法.
将字符串写入到指定的文件中
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)error;
参数解释:
第 1 个参数: 路径.
要将字符串写入到 1 个文件之中.
第 2 个参数: 保证原子性.
如果为 YES 则会先创建 1 个临时文件,将内容写到这个临时文件中.如果成功再将临时文件拷贝到指 定的目录. 这样做的好处是安全,不易出错.但是效率较低. 如果为 NO,直接将字符 串写到指定的文件之中.这样写不 安全 但是效率高. 建议使用 NO.
第 3 个参数: 以哪种字符编码将字符串数据写入到文件,这里传入:NSUTF8StringEncoding
第 4 个参数: 二级指针.传入 1 个 NSError 的 1 个二级指针.
如果方法执行成功.则方法执行完毕之后. 这个 NSError 的指针的值为 nil 如果方法执行失败.则方法执行完毕之后 这个 NSErro 指针会指向 1 个错误对象. 可以打印这个错误对 象得到发生错误的详细信息.
调用 NSError 对象的 localizedDescription 方法 可以拿到发生错误的简要发生原因.
所以,判断是否写入成功就可以判断这个 NSError 指针是否为 nil 如果为 nil 说明写入成功,如果不为 nil 就说明写入失败.
返回值 BOOL.代表是否写入成功.
从指定文件中读取字符串数据
+ (nullable instancetype)stringWithContentsOfFile:(NSString *)path encoding:(NSStringEncoding)enc error:(NSError **)error;
nullable 代表返回的对象有可能是nil
参数解释:
第 1 个参数: 路径
要读取那 1 个文件中的字符串数据.
第 2 个参数: 使用的字符编码
建议使用 NSUTF8StringEncoding
第 3 个参数: 二级指针.传入 1 个 NSError 的 1 个二级指针.
如果方法执行成功.则方法执行完毕之后. 这个 NSError 的指针的值为 nil
如果方法执行失败.则方法执行完毕之后 这个 NSErro 指针会指向 1 个错误对象.可以打印这个错误 对象得到发生错误的详细信息.
所以,判断是否读取成功就可以判断这个 NSError 指针是否为 nil 如果为 nil 说明读取成功,如果不为 nil 就说明读取失败.
返回值是 NSString 返回的是从指定文件中读取出来的字符串数据.
使用NSURL读写字符串数据.
1).读写字符串数据的时候.路径可以是本地磁盘路径,也可以是 1 个网址,还可以是 1 个 ftp 文件的地址.
我们使用 1 个 NSURL 对象来描述这样 1 个地址.本地路径的 网址的 ftp 文件的地址.
我们就可以通过这个 NSURL 对象存储的地址信息 来读写字符串.
2). 不同的 URL 的写法,根据协议区分.
本地文件: file://绝对路径
网址: http://网址 或者 https://网址.
ftp: ftp://文件地址
3). 将地址信息包装在 1 个 NSURL 对象之中.
-> 将本地文件路径封装在 NSURL 对象之中.
NSURL *url = [NSURL URLWithString:@"file:///Users/Highven/Desktop/123.txt"];
-> 将网页地址路径封装在 NSURL 对象之中.
NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
-> 将 ftp 文件路径封装在 NSURL 对象之中.
NSURL *url = [NSURL URLWithString:@"ftp://XXXXXXX/cjk.txt"];
4). 读取 NSURL 对象中保持的路径的文件数据.
+ (nullable instancetype)stringWithContentsOfURL:(NSURL *)url encoding:(NSStringEncoding)enc error:(NSError **)error;
第 1 个参数: 封装了地址的 NSURL 对象.
第 2 个参数: 编码方式,一般传递 NSUTF8StringEncoding
第 3 个参数: 二级指针.传入 1 个 NSError 的 1 个二级指针.
如果方法执行成功.则方法执行完毕之后. 这个 NSError 的指针的值为 nil
如果方法执行失败.则方法执行完毕之后 这个 NSErro 指针会指向 1 个错误对象.可以打印这个错误对象得 到发生错误的详细信息.
所以,判断是否读取成功就可以判断这个 NSError 指针是否为 nil 如果为 nil 说明读取成功,如果不为 nil 就说明读取失败.
返回值.为读取到的字符串数据.
如果 NSURL 对象中保存的地址是本地文件的地址.就会去指定的本地文件中读取字符串数据.
如果 NSURL 对象中保存的地址是 1 个网页地址.就会去下载这个网页的源代码.
如果 NSURL 对象中保存的地址是 1 个 ftp 文件地址.就会去下载这个文件的内容.
向 NSURL 对象保持的地址写入字符串数据.
需要注意的是,不能向网页、ftp 写入字符数据.除非你拥有写入的权限.
- (BOOL)writeToURL:(NSURL *)url atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)error;
第 1 个参数: 封装了地址的 NSURL 对象.
第 2 个参数: 保证原子性.
如果为 YES 则会先创建 1 个临时文件,将内容写到这个临时文件中.如果成功再将临时文件拷贝到 指定的目录. 这样做的好处是安全,不易出错.但是效率较低. 如果为 NO,直接将字符串写到指定的文件之中.这样写 不安全 但是效率高. 建议使用 NO.
第 3 个参数: 以哪种字符编码将字符串数据写入到文件
这里传入:NSUTF8StringEncoding
第 4 个参数: 二级指针.传入 1 个 NSError 的 1 个二级指针.
如果方法执行成功.则方法执行完毕之后. 这个 NSError 的指针的值为 nil 如果方法执行失败.则方法执行完毕之后 这个 NSErro 指针会指向 1 个错误对象. 可以打印这个错误对象得到发生错误的详细信息.
调用 NSError 对象的 localizedDescription 方法 可以拿到发生错误的简要发生原因. 所以,判断是否写入成功就可以判断这个 NSError 指针是否为 nil
如果为 nil 说明写入成功,如果不为 nil 就说明写入失败. 返回值 BOOL.代表是否写入成功.
字符串的比较
1). 字符串比较的第一种方式.调用字符串对象的 compare:方法
- (NSComparisonResult)compare:(NSString *)string;
比较的原理: 比 ASCII 码 比较两个字符串的第 0 个字符的 ASCII 的大小.如果相等再比较下 1 个.
返回值是 1个NSComparisonResut 类型的枚举.
实际上,你完全可以使用 1 个 int 类型的变量来接收这个结果.
如果返回的是:1 说明当前这个字符串小于传入的字符串.
如果返回的是 0 说明当前字符串和传入的字符串的内容是相等的.
如果返回的是 1 说明当前字符串和传入的字符串大大于的.
NSNumericSearch: 比较的是两个同样格式的字符串中,数字的大小.
2). 比较字符串的第二种方式:
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask;
指定比较选项.
options 参数: 枚举类型, 指定比较选项
NSCaseInsensitiveSearch: 忽略大小写的比较.
NSLiteralSearch: 完全匹配的比较.
字符串相等的判断
1). 第 1 个非常严肃的问题.
就是判断两个字符串的内容是否相同,能否使用 == 比较运算符来判断.
首先,我们要搞清楚 == 比较运算符的作用是什么?
== 运算符是用来比较两边的两个数据是否是相等的.
如果==运算符的两边是 1 个变量的话.那么比较的是两个变量的值是否相等.
如果使用==比较的是两个指针变量呢? 比较的是这两个指针变量的值. 仍然比较的是变量的值.
如果比较的是两个 NSString 的指针变量呢?
所以,如果要判断两个字符串相等,不应该判断字符串的指针的值是否相等.而是应该判断指针指向的字符 串对象中的内容是否相等.
2).判断 NSString 指针指向的字符串对象的内容是否相等.
- (BOOL)isEqualToString:(NSString *)aString;
NSRange 概述
NSRange 是 Foundation 框架中比较常用的结构体.它的定义如下.
NSUInteger 的定义如下:
一个 NSRange 结构体变量表示 1 段范围. 通常情况下,用来表示 1 个子字符串在主字符串中的范围.
该结构体有两个成员:
location 表示这个范围的起始位置下标.
length: 表示该范围内的长度.
声明并初始化结构体变量的方式.
1). 最原始的方式.
NSRange range;
range.location = 3;
range.length = 4;
2). 第二种方式: NSRange range = {3, 7};
3). 第三种方式: NSRange range = {.location = 3,.length = 7};
4). Foundation框架中定义了1个函数.这个函数可以快速的创建1个NSRange结构体会,
NSRange range = NSMakeRange(loc, len);
返回1个指定属性的NSRange结构体变量.
5). Foundation框架中定义了1个函数 可以将1个NSRange结构体变量转换为NSString
NSStringFromRange(ran) 函数可以将NSRange结构体变量转换为指定格式的字符串.
判断 1 个字符串中是否包含 1 个子字符串.
- (NSRange)rangeOfString:(NSString *)searchString;
举个例子. @”我爱北京” 判断这个字符串中是否有 @”爱北” 这个子字符串.
返回值是 1 个 NSRange 的 1 个结构体数据.代表子字符串在字符串中的范围.
这个方法,会返回这么 1 个结构体变量,表示子字符串在主字符串中的范围.
location : 代表子字符串在主字符串中第 1 次出现的下标.如果没有找到,就将是最大值.
length: 代表子字符串在主字符串中匹配的字符个数的长度,如果没有找到. 则为 0 如果找到了和子字符串的长 度一致.
所以,判断主字符串中是否包含子字符串,只需要判断返回的 NSRange 结构体变量的 length 是否为 0 就可以.
! 也可以查找主字符串中子字符串最后 1 次出现的范围.
- (NSRange)rangeOfString:(NSString *)searchString options:(NSStringCompareOptions)mask;
mask 设置为 NSBackwardsSearch
字符串的截取
从 1 个字符串中,取出 1 个子字符串来.
从字符中指定的下标截取到最后.
- (NSString *)substringFromIndex:(NSUInteger)from;
参数: 传入 1 个下标,就从这个下标开始一直截取到最后.
从第 0 个元素截取到指定的下标.
- (NSString *)substringToIndex:(NSUInteger)to;
参数:传入 1 个下标,就会从第 0 个元素截取到这个下标处.不包括这个下标的字符
从字符串中截取 1 个范围的子字符串.
- (NSString *)substringWithRange:(NSRange)range; 截取指定的1段范围.
参数: 传入 1 个 NSRange 结构体变量 表示要从主字符串的那 1 个位置开始截取多少个长度的子字符串.
字符串的替换
- (NSString *)stringByReplacingOccurrencesOfString:(NSString *)target withString:(NSString *)replacement
将字符串中第1个参数替换为第2个参数.友情提示: 原来的指针指向字符串的内容是不会变的 会全部替换.
新串是以方法的返回值返回的.
这个方法还可以做删除. 原理: 将其替换为@""
去掉字符串前后的空格.
str = [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
中间的空格无法去掉.
获取字符串中的每一个字符
@“jacklove 小花”. 要取出这个字符串中的每 1 个字符.或者指定下标的字符.
- (unichar)characterAtIndex:(NSUInteger)index;
传入 1 个 NSUInteger 的参数.就会返回这个下标处的字符. 返回值是 unichar 类型的.这个类型的字符支持中文.
输出 unichar 变量中的字符数据使用格式控制符 %C 看清楚是大写的 C
字符串数据转换为其他的类型. 使用频率很高.
@property (readonly) double doubleValue;
@property (readonly) float floatValue;
@property (readonly) int intValue;
@property (readonly) NSInteger integerValue
@property (readonly) long long longLongValue
@property (readonly) BOOL boolValue
需要特别注意 1 点是: 如果字符串的字面量不是纯的数字.在转换的时候能转换多少是多少. 比如: @”12a” 转换为 int 是 12
@“a12” 是无法转换为 int 所以就返回 0
将 OC 字符串转换为 C 语言的字符串
NSString *ttt=@"aaaa";
char* aaa=ttt.UTF8String
将 C 语言的字符串转换为 OC 的字符串
+ (nullable instancetype)stringWithUTF8String:(const char *)nullTerminatedCString;
得到字符串的长度
调用字符串对象的 length 方法就可以.
@property (readonly) NSUInteger length;
去除字符串的前后空格
- (NSString *)stringByTrimmingCharactersInSet:(NSCharacterSet *)set;
[ttt stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
将字符串转换为大写字符串
@property (readonly, copy) NSString *uppercaseString;
将字符串转换为小写字符串.
@property (readonly, copy) NSString *lowercaseString;
去掉字符串前后的小写字母
- (NSString *)stringByTrimmingCharactersInSet:(NSCharacterSet *)set;
[ttt stringByTrimmingCharactersInSet:[NSCharacterSet lowercaseLetterCharacterSet]];
去掉字符串前后的大写字母
- (NSString *)stringByTrimmingCharactersInSet:(NSCharacterSet *)set;
[ttt stringByTrimmingCharactersInSet:[NSCharacterSet uppercaseLetterCharacterSet]];
去掉头尾指定的字符串.
- (NSString *)stringByTrimmingCharactersInSet:(NSCharacterSet *)set;
[ttt stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"abcdef"]];