百家汽车网
您的当前位置:首页OC学习--NSString的三种实现形式

OC学习--NSString的三种实现形式

来源:百家汽车网


前言

当被学长问到NSString的三种实现形式时,大脑是空白的。
通过学习学长们的博客,查阅资料,悔不当初没有好好学习。
现在,让我们来探索一下OC中NSString的三种形式吧~


NSString三种类型的出现

#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSString *a = @"hello";
        NSString *b = @"hello,iOS!";
        NSString *c = [NSString stringWithFormat:@"hello"];
        NSString *d = [NSString stringWithFormat:@"hello,iOS!"]; 
        NSString *e = [NSString stringWithFormat:@"嗨"];
        NSLog(@"%p %@ \n %p %@ \n%p %@\n %p %@ \n%p %@", a, [a class], b, [b class] , c, [c class], d, [d class], e, [e class]);
    }
    return 0;
}

运行上述代码,我们会发现同样是NSString类型,但是有三种不同的类型


__NSCFConstantString

该类型正如其名字,是一种Constant常量型字符串。创建方式即是@""直接创建,储存在字符串常量区中。

		//创建方式
        NSString *a = @"hello";
        NSString *b = @"hello,iOS!";
        //stringWithString类方法创建,等同于@“”
         NSString *c3 = [NSString stringWithString:@"hello"];

该类型有如下特点:

  • 作为常量字符串,是一种编译时常量
  • 储存在字符串常量区
  • retainCount的值非常大,无法被释放
  • 使用不同的字符串对象进行创建时,只要内容相同,则对象的地址也相同。
        NSString *c1 = @"hello";
        NSString *c2 = @"hello";
        NSString *c3 = [NSString stringWithString:@"hello"];
        
        NSLog(@"c1: %p %@ \nc2: %p %@\nc3: %p %@", c1, [c1 class], c2, [c2 class], c3, [c3 class]);

运行结果如下所示:


__NSCFString

该类型与__NSCFConstantString不同,是在运行时创建的NSString子类,并不是字符串常量类型,在被创建时获得了1的引用计数,因此是可以被释放的。该类型有如下特点:

  • 运行时创建,储存在堆上。因此使用相同的内容创建字符串对象时,字符串对象的地址也不相同。
  • 使用stringWithFormat的类方法创建该对象时,一般都是__NSCFString类。
  • 当字符串长度大于9时,以该类储存,但如果小于9,则会变成NSTaggedPointerString类。
  • 如果字符串对象的内容是中文,则无论长短,都是__NSCFString类。

该类型的创建需要使用stringWithFormat类方法(注意,使用stringWithString的实例方法创建的是__NSCFConstantString类):

        NSString *d = [NSString stringWithFormat:@"hello,iOS!"]; 
        NSString *e = [NSString stringWithFormat:@"嗨"];

NSTaggedPointerString

学习这一类型,我们首先要认识标签指针的概念,这里转载一下学长博客的内容。

对于NSTaggedPointerString类型,有如下特点:

  • 引用计数很大,是一个无法释放的单例常量对象,使用不同的字符串对象进行创建时当内容相同时,字符串对象的地址也相同,但是是在运行时创建
  • 使用stringWithForma类方法创建字符串对象时,当非字面值常量的数字,英文字母字符串的长度小于等于9(来源于学长博客的数据)时,会自动成为NSTaggedPointerString类。

我们以下面这段代码来探究该类:

NSString *t1 = [NSString stringWithFormat:@"loveiOS"];
        NSString *t2 = [NSString stringWithFormat:@"哈"];
        NSString *t3 = [NSString stringWithFormat:@"doyoulikeiOS"];
        NSLog(@"t1: %p %@ \nt2: %p %@\nt3: %p %@", t1, [t1 class], t2, [t2 class], t3, [t3 class]);

这是结果:


总结

__NSCFString:在运行时创建的一种 NSString 子类,被储存在堆区即动态区。


感谢学长学姐们为我们学习带来的便利,往后要更加提高学习的主动性,多探索,多学习,多实践。

因篇幅问题不能全部显示,请点此查看更多更全内容