在oc中蓄氧,經(jīng)常會用到常量字符串苔巨,常量字符串和一般字符串還是有一定區(qū)別的。
NSString * string1 = @"Hello";
NSString * string2 = @"Hello";
if (string1 == string2) {
NSLog(@"They are same address");
}
對字符串常量string1 和string2進行比較喘垂,就會發(fā)現(xiàn)甜刻,二者竟然是相等的。產(chǎn)生這樣的原因要歸咎于編譯器優(yōu)化的結果正勒。
由于常量會占用一塊特殊的代碼段得院,加載到內(nèi)存時,就會映射到一塊常量存儲區(qū)章贞,以加快訪問速度祥绞。編譯器在編譯時會發(fā)現(xiàn),string1和string2的內(nèi)存是相同的常量字符串鸭限,會把他們都指向相同的一個區(qū)域蜕径,而不是開辟出一個額外的內(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!");
}
首先兜喻,申明上的這一段代碼不是一段合法的代碼,因為在第二行alloc之后赡麦,沒有立即init朴皆。雖然這種做法是非常不推薦的,但是這次為了更清晰的說明問題隧甚,不得已而為之车荔。
通過程序比較分析,就是發(fā)現(xiàn)string2和string3的地址值竟然不相等戚扳,而string1和string3竟然相等。通過這些可看出族吻,如果使用一個常量字符串來初始化另一個字符串帽借,另一個字符串會直接通過地址賦值為常量字符串珠增,alloc的內(nèi)存也會立即釋放。
另外砍艾,常量字符串不會release蒂教。
要點###
(1)由于編譯器的優(yōu)化,相同內(nèi)容的常量字符串的地址值是完全相同的脆荷。
(2)如果使用常量字符串來初始化一個字符串凝垛,那么這個字符串也是相同的常量。
(3)對常量字符串來說蜓谋,永遠不要release梦皮。