在oc中,經(jīng)常會(huì)用到常量字符串,常量字符串和一般字符串還是有一定區(qū)別的。
NSString * string1 = @"Hello";
NSString * string2 = @"Hello";
if (string1 == string2) {
NSLog(@"They are same address");
}
對(duì)字符串常量string1 和string2進(jìn)行比較,就會(huì)發(fā)現(xiàn),二者竟然是相等的。產(chǎn)生這樣的原因要?dú)w咎于編譯器優(yōu)化的結(jié)果。
由于常量會(huì)占用一塊特殊的代碼段,加載到內(nèi)存時(shí),就會(huì)映射到一塊常量存儲(chǔ)區(qū),以加快訪問(wèn)速度。編譯器在編譯時(shí)會(huì)發(fā)現(xiàn),string1和string2的內(nèi)存是相同的常量字符串,會(huì)把他們都指向相同的一個(gè)區(qū)域,而不是開(kāi)辟出一個(gè)額外的內(nèi)存空間。因此他們的地址是相同的。
再看看這段代碼:
NSString * string1 = @"Hello";
NSString * string2 = [NSString alloc];
NSString * string3 = [string2 initWintStirng:string1];
if (string2 != string3){
NSLog(@"string2 are not asme to string3!");
}
if (string1 == string3){
NSLog(@"string1 are same to string3!");
}
首先,申明上的這一段代碼不是一段合法的代碼,因?yàn)樵诘诙衋lloc之后,沒(méi)有立即init。雖然這種做法是非常不推薦的,但是這次為了更清晰的說(shuō)明問(wèn)題,不得已而為之。
通過(guò)程序比較分析,就是發(fā)現(xiàn)string2和string3的地址值竟然不相等,而string1和string3竟然相等。通過(guò)這些可看出,如果使用一個(gè)常量字符串來(lái)初始化另一個(gè)字符串,另一個(gè)字符串會(huì)直接通過(guò)地址賦值為常量字符串,alloc的內(nèi)存也會(huì)立即釋放。
另外,常量字符串不會(huì)release。
要點(diǎn)###
(1)由于編譯器的優(yōu)化,相同內(nèi)容的常量字符串的地址值是完全相同的。
(2)如果使用常量字符串來(lái)初始化一個(gè)字符串,那么這個(gè)字符串也是相同的常量。
(3)對(duì)常量字符串來(lái)說(shuō),永遠(yuǎn)不要release。