參考文章
我遇到的問題
知識補充:以字面量形式或者 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;
});
}
複製程式碼
這段程式碼也是使用的比較長的那個字串。在第一段程式碼中,它崩了,在這段裡面,它沒崩。為什麼?