在Objective-C裡有一種記憶體管理機制叫做Reference Counting,是說當某個物件生成並初始化之後,它的retain count會設定成1。執行該物件的”retain”方法會讓該物件的retain count加1,而release方法會讓retain count減1。當該物件的retain count變成0的時候,這個物件自動會呼叫dealloc方法,然後把記憶體還回來,Objective-C的書上或是官方手冊裡差不多都是這樣教的。
所以,下面的程式碼,2個物件的retain count預期應該會是1:
1 2 3 4 5 | |
輸出結果是:
retain count of n1 is 2
retain count of n2 is 1
n2的retain count是1沒問題,但n1的卻是2,這結果跟我想像的不太一樣,這令我這個初學者很困惑..我知道retainCount不應該被拿來做為流程裡的邏輯判斷的依據,不過我很好奇為什麼會有這樣的差異?
翻了一下網路上的討論,原來是說因為某些數字太常被用到,為了做一些最佳化,所以在系統裡直接就預先產生了一份,再試了一下以下的程式碼:
1 2 3 4 5 6 7 8 9 10 11 | |
結果是:
retain count of n1 is 2
retain count of n2 is 1
retain count of n3 is 1
retain count of n4 is 3
又試著把他們的位址印出來:
1 2 3 4 5 | |
結果是:
address of n1 is 0x100108e20
address of n2 is 0x10010cb30
address of n3 is 0x10010cb50
address of n4 is 0x100108e20
這樣似乎就能解釋retain count跟預期不太一樣的原因了,可以看到n1跟n4是指向同一塊記憶體位置,而n2跟n3是不同的位置,retain count都是1,表示n2跟n3在生成的時候是建立一個新的數字,而n1跟n4則是指向一個像是”預先產生而且共享”的數字,所以n1一開始的 retain count是2,n4因為指向跟n1同一個地方,所以retain count變3。而這個最佳化(預先產生)的範圍,似乎是從-1 ~ 12之間。
果然還有很多要學的 :)
新手上路,若有錯誤還請不吝指教!