参考文章
我遇到的问题
知识补充:以字面量形式或者 initWithString: 创建出来的字符串是在常量区的,不会释放。以 stringWithFormat: 创建出来的是在堆上。
- string1 与 string3 是 __NSCFConstantString 类型的,它们是在常量区的。
- string4 是 __NSCFString 类型的,它的地址比 string1 与 string3 高的多,它是在堆上的。
- string2 是 NSTaggedPointerString 类型的。它的地址的第一位位是 a (十六进制),如果在二进制下,这个地址的首位为 1。地址首位为 1,在 iOS 平台下,就是 TaggedPointer 处理过的(看源码可以知道)。
问题一
@property (nonatomic, copy) NSString * name;
for (int i = 0; i < 1000; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
self.name = [NSString stringWithFormat:@"abcdefghij"];
});
}
for (int i = 0; i < 1000; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
self.name = [NSString stringWithFormat:@"abcdefghi"];
});
}
第一段代码会崩溃,因为在 - setName: 方法中多次释放 _name。
第二段代码不会崩溃,它与第一个不同的是,这个字符串比较短,采用的是 taggedpointer 技术。 它为什么不崩溃,暂时不太理解?我打上断点发现每次都会进入- setName: 方法,那么每次进来都会有 release 才对。
问题二
for (int i = 0; i < 1000; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
self.name = @"abcdefghij";
});
}
这段代码是使用的比更长的那个字符串。
这段代码也不会崩溃。
它是创建在常量区的。
它为什么不崩溃,我也不知道。
问题三
NSString *string = [NSString stringWithFormat:@"abcdefghij"];
for (int i = 0; i < 1000; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
self.name = string;
});
}
这段代码也是使用的比较长的那个字符串。在第一段代码中,它崩了,在这段里面,它没崩。为什么?