Objective-C 的 NSString是该语言的字符串模块,就字符串而言C语言也有自己的字符串模块封装,但NSString以对象的方式封装,而且支持各种编码,算是一个强化版本的字符串模块了,但是和原始C语言的字符串相比,速度慢了10倍有余。

OC中NSString创建字符串的方法可以如下。奇怪的是,百度上说第二种方法创建速度更快,然而我通过1e5,1e6,1e7三次迭代测试发现直接引用的创建方法更快,当然了这两种都远远不如C语言版本char *str直接方法穿件:

NSString *str = @"balabalabala";
NSString *Str = [[NSString alloc] initWithString:@"balabalabala"];
1.操作Unicode编码字符串

NSString中的汉字都是用Unicode表示,,下面摘抄了一些不错的API,值得注意的是length返回编码字符的个数,对于C语言中如果输入的是中文交给了一个字符串,那么该字符串的length会double,因为一个字符占用两个char,而且也相当不好进行一些reversed order这类型的操作。

-(id) initWithUTF8String: (const char *) bytes
/*以从NULL结束的UTF8编码的C字符串中复制信息,并且初始化接受者*/

-(__strong const char *)UTF8String
/*返回编码为UTF,以NULL结尾的C语言字符串的指针。基于引用计数的内存管理模式下,返回的字符串会在消息接收独享被释放的同事被释放掉,如果想在对象被释放之后也能使用,就需要额外复制一份。GC的内存管理模式下,因为返回的指针是强指针,所以不会被GC回收*/

-(NSUInteger) length
/*返回字符串中Unicode编码的字符个数。和C风格的字符串不同,不能用这个函数返回值来计算需要的字节数和表示时需要的 长度 */


//……and more
2.编码风格转换

以下是一些常用的编码转换的API,注意ascii的定义有的时候是用是旧的char方法(7bits),而有时候则是新版的unsigned char方法(8bits),关于UTF,也有8bit和16bit版本的区分,请注意细节。

NSASCIIStringEncoding 7位版的ASCII编码(低7位表示不同的ASCII字符,字节的最高位固定为0
NSNEXTSTEPStringEncoding 8位版的ASCII编码(NEXTSTEP扩展)
NSUnicodeStringEncoding 正规的Unicode编码(UTF-16
NSUTF8StringEncoding 8位的Unicode字符串(UTF-8
NSNonLossyASCIIStringEncoding 7位的无损Unicode编码
NSISOLatin1StringEncoding 8位的ISO Latin 1编码
NSISOLatin2StringEncoding 8位的ISO Latin 2编码
NSMacOSRomanStringEncoding Mac OS编码
NSWindowsCP1252StringEncoding Windows Windows Latin1
NSWindowsCP1250StringEncoding Windows Windows Latin2
NSSymbolStringEncoding 8 Adobe Symbol编码向量
NSJapaneseEUCStringEncoding 8位日语EUC编码
NSShiftJISStringEncoding 8位日语Shift-JIS编码
NSISO2022JPStringEncoding ISO 2022电子邮件用日语编码
3.生成指定格式的字符串

需要注意的就是Unicode和ascii码占据空间是不一样的,比如我下面这个代码,分别测试一下正确和错误的。

int main(int argc, const char * argv[]) {
    NSString *str = @"怎么哪里都有砸总的,WD!";
    NSLog(@"%@",str);
    unsigned long cnt = [str length];
    for(unsigned int i = 0; i < cnt; i++){
        unichar c = [str characterAtIndex:i];   //正确方法
        //char c = [str characterAtIndex:i];    //错误方法
        /*
         中文出错原因猜测,原本NSString采用Unicode格式16bit,而C语言的char采用7bit格式
         直接[str characterAtIndex]返回Unicode格式的一个字符,占据16bit,如 5000 1000 0000 0005
         而char只接受8bit位,发生了截断 如上数据就只接受了 0000 0005
         而Unicode在低位兼容ASCII码,因此英文的读取是正常的
         解决思想:从OC的标准库中找到一个能够单独提取UTF8格式单个字符的容器,利用它进行输出
         解决方法:用unichar代替char,用%C代替%c
         */
        NSLog(@"字符串第 %d 位 为 %C",i,c);       //正确方法
        //NSLog(@"字符串第 %d 位 为 %c",i,c);     //错误方法
    }
    return 0;
}

对于常见的格式而言,可以参考如下内容,重点注意如下两个点

  1. %@对应的参数必须是一个对象。当输出%@时(列如:NSLog(@”%@”, test);),实际上就是调用了test的description方法,返回的结果储存到%@中。description方法是NSObject中定义的方法,任何对象都可以调用它。description返回的内容和类的实现相关。
  2. C语言的printf()中,编译器支持参数类型的自动转换,列如你可以吧int定义的数字用%.f输出,反之用%f输入的数字也可以交给一个整型。而OC的NSString则不支持这种参数类型的自动转换,所以一定要保证格式化字符串中指定的类型和所传入的参数类型一致。

NSLog常用的标记符,NSLog和NSString是结合最密切的两个类了,注意%@表示对象,用NSString生成的字符串其实就是一个对象,所以应该使用%@而不能像c语言字符串那样%s.

/*
========== NSLog使用 ==========
    //    %@        对象
    //    %d, %i    整数
    //    %u          无符整型
    //    %f           浮点/双字
    //    %x, %X      二进制整数
    //    %o          八进制整数
    //    %zu        size_t
    //    %p          指针
    //    %e          浮点/双字 (科学计算)
    //    %g          浮点/双字
    //    %s C      字符串
    //    %.*s        Pascal字符串
    //    %c           字符
    //    %C          unichar
    //    %lld        64位长整数(long long)
    //    %llu        无符64位长整数
    //    %Lf         64位双字
*/

特别注意一下这个API

-(id) initWithFormat:(NSString *) format, ...
/*
根据format中指定的格式串来生成一个字符串,使用这个字符串来初始化消息接受者。format中参数用逗号分隔,格式字符串不能为空。
便利构造器:stringWithFormat:
*/

注:和C语言一样,OC也支持可变参数,用…表示,详情可以看这个blog:http://c.biancheng.net/view/344.html

其他功能诸如:NSString的比较,追加截取,检索和置换,大小写处理,数值转换,文件路径处理(”Foundation/NSPathUtilities.h”)等内容可以自己翻阅API,OC的一个风格点就是汇总的好,按照大功能模块合并

n.文件输入输出

从文件中读取字符串的内容,也可以将字符串的内容输出到文件中。另外,下面这些同文件相关的方法都带有一个error参数,并把发生错误时的信息写入到error中。error不能为NULL,否则就不会返回任何错误信息。

有如下两个API常用。

-(id) initWithContentsOfFile : (NSString *) path
                               encoding : (NSStringEncoding) enc
                                      error : (NSError **) error
/*
通过读取文件path中的内容来初始化一个NSString,文件的编码为enc。读取文件失败的时候会释放调用者,并在返回nil的同事将详细的错误信息设定到error。
便利构造器:stringWithContentsOfFile : encoing : error:
*/

-(id) initWithContentsOfFile : (NSString *) path
                      usedEncoding : (NSStringEncoding) enc
                                      error : (NSError **) error
/*
和上一个方法一样,通过读取文件path中的内容来初始化一个NSString。不同的地方在于这个函数能够自动判别文件的编码,并通过enc返回。文件的编码是通过文件的内容和文件的扩展属性(extended attribute)来判断的。
更多请参考命令xattr
*/

1 条评论

OC – Foundation模块详细学习笔记 – 木十的博客 · 2021年3月15日 下午3:13

[…] OC – NSString 字符串类详解 […]

发表回复

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用 * 标注