35.用“僵尸對(duì)象”調(diào)試內(nèi)存管理問題

《編寫高質(zhì)量iOS與OS X代碼的52個(gè)有效方法》--第五章 第35條
(ps:此乃讀書筆記漂问,加深記憶,僅供大家參考)


第35條 用“僵尸對(duì)象”調(diào)試內(nèi)存管理問題

大家都知道,向業(yè)已回收的對(duì)象發(fā)送消息是不安全的。這么做有時(shí)可以捉撮,有時(shí)不行。具體可行與否妇垢,完全取決于對(duì)象所占內(nèi)存有沒有為其他內(nèi)容所覆寫巾遭。

所幸Cocoa提供了“僵尸對(duì)象”(Zoombie Object)這個(gè)非常方便的功能肉康。啟用這項(xiàng)調(diào)試功能之后,運(yùn)行期系統(tǒng)會(huì)把所有已回收的實(shí)例轉(zhuǎn)化成特殊的“僵尸對(duì)象”灼舍,而不會(huì)真正回收它們迎罗。這種對(duì)象所在的核心內(nèi)存無法重用,因此不可能遭到覆寫片仿。僵尸對(duì)象收到消息后纹安,會(huì)拋出異常,其中準(zhǔn)確說明了發(fā)送過來的消息砂豌,并描述了回收之前的那個(gè)對(duì)象厢岂。僵尸對(duì)象是調(diào)試內(nèi)存管理問題的最佳方式。

僵尸對(duì)象的工作原理是什么阳距?它的實(shí)現(xiàn)代碼深植于Objective-C的運(yùn)行期程序庫塔粒、Foundation框架及CoreFoundation框架中。系統(tǒng)在即將回收對(duì)象時(shí)筐摘,如果發(fā)現(xiàn)通過環(huán)境變量啟用了僵尸對(duì)象功能卒茬,那么還將執(zhí)行一個(gè)附加步驟。這一步驟就是把對(duì)象轉(zhuǎn)化為僵尸對(duì)象咖熟,而不徹底回收圃酵。

void PrintClassInfo(id obj){
    Class cls = object_getClass(obj);
    Class superCls = class_getSuperclass(cls);
    NSLog(@"=== %s : %s ===", class_getName(cls), class_getName(superCls));
}

int main(int argc, char *argv[])
{
    EOCClass *obj = [[EOCClass alloc] init];
    NSLog(@"Before release:");
    PrintClassInfo(obj);

    [obj release];
    NSLog(@"After release:");
    PrintClassInfo(obj);
}

范例代碼將輸出下面這種消息:

Before release:
=== EOCClass : NSObject ===
After release:
=== _NSZombie_EOCClaxx : nil ===

_NSZombie_EOCClaxx實(shí)際上是在運(yùn)行期生成的,當(dāng)首次碰到EOCClass類的對(duì)象要變成僵尸對(duì)象時(shí)馍管,就會(huì)創(chuàng)建這么一個(gè)類郭赐。創(chuàng)建過程中用到了運(yùn)行期程序庫里的函數(shù),他們的功能很強(qiáng)大确沸,可以操作類列表(class list)捌锭。

僵尸類(zoombie class)是從名為NSZombie的模板類里復(fù)制出來的。這些僵尸類沒有多少事情可做罗捎,只是充當(dāng)一個(gè)標(biāo)記观谦。

僵尸類的作用會(huì)在消息轉(zhuǎn)發(fā)例程(參見12條)中體現(xiàn)出來。NSZombie類(以及所有從該類拷貝出來的類)并未實(shí)現(xiàn)任何方法桨菜。此類沒有超類豁状,因此和NSObject一樣,也是個(gè)“根類”雷激,該類只有一個(gè)實(shí)例變量替蔬,叫做isa,所有NSObjective-C的根類都必須由此變量屎暇。由于這個(gè)輕量級(jí)的類沒有實(shí)現(xiàn)任何方法,所以發(fā)給它的全部消息都要經(jīng)過“完整的消息轉(zhuǎn)發(fā)機(jī)制”(full forwarding mechanism驻粟, 參見第12條)根悼。

在完整的消息轉(zhuǎn)發(fā)機(jī)制中凶异,forwarding是核心,調(diào)試程序時(shí)挤巡,大家可能在検1颍回溯消息里看見過這個(gè)函數(shù)。它首先要做的事情就包括檢查接收消息的對(duì)象所屬的類名矿卑。若名稱前綴為NSZombie喉恋,則表明消息接收者是僵尸對(duì)象,需要特殊處理母廷。此時(shí)會(huì)打印一條消息轻黑,其中指明了僵尸對(duì)象所受到的消息及原來所屬的類,然后應(yīng)用程序就終止了琴昆。

* * * -[CFString respondsToSelector:]: message sent to deallocated instance 0x7ff9e9c080e0

把本節(jié)開頭那個(gè)范例擴(kuò)充一下氓鄙,試著給變成僵尸的EOCClass對(duì)象發(fā)送description消息:

EOCClass *obj = [[EOCClass alloc] init];
NSLog(@"Before release:");
PrintClassInfo(obj);

[obj release];
NSLog(@"After release:");
PrintClassInfo(obj);

[obj description];

若是開啟了僵尸對(duì)象功能,那么控制條會(huì)輸出下列消息:

Before release:
=== EOCClass : NSObject ===
After release:
=== _NSZombie_EOCClass : nil ===
*** -[EOCClass description]: message sent to deallocated instance 0x7fb81bdce9b0

要點(diǎn)

  • 系統(tǒng)在回收對(duì)象時(shí)业舍,可以不將其真的回收抖拦,而是把它轉(zhuǎn)化為僵尸對(duì)象。通過環(huán)境變量NSZombieEnable可開啟此功能
  • 系統(tǒng)會(huì)修改對(duì)象的isa指針舷暮,令其指向特殊的僵尸類态罪,從而使該對(duì)象變?yōu)榻┦瑢?duì)象。僵尸類能夠響應(yīng)所有的選擇子下面,響應(yīng)方式為:打印一條包含消息內(nèi)容及其接受者的消息向臀,然后終止應(yīng)用程序。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末诸狭,一起剝皮案震驚了整個(gè)濱河市券膀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌驯遇,老刑警劉巖芹彬,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異叉庐,居然都是意外死亡舒帮,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門陡叠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來玩郊,“玉大人,你說我怎么就攤上這事枉阵∫牒欤” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵兴溜,是天一觀的道長(zhǎng)侦厚。 經(jīng)常有香客問我耻陕,道長(zhǎng),這世上最難降的妖魔是什么刨沦? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任诗宣,我火速辦了婚禮,結(jié)果婚禮上想诅,老公的妹妹穿的比我還像新娘召庞。我一直安慰自己,他們只是感情好来破,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布篮灼。 她就那樣靜靜地躺著,像睡著了一般讳癌。 火紅的嫁衣襯著肌膚如雪穿稳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天晌坤,我揣著相機(jī)與錄音逢艘,去河邊找鬼。 笑死骤菠,一個(gè)胖子當(dāng)著我的面吹牛它改,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播商乎,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼鹉戚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起抹凳,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎赢底,沒想到半個(gè)月后失都,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體幸冻,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年洽损,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了庞溜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡趁啸,死狀恐怖强缘,靈堂內(nèi)的尸體忽然破棺而出督惰,到底是詐尸還是另有隱情不傅,我是刑警寧澤旅掂,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站访娶,受9級(jí)特大地震影響商虐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜崖疤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一秘车、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧劫哼,春花似錦叮趴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至般码,卻和暖如春妻率,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背板祝。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工宫静, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人券时。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓孤里,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親橘洞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子捌袜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 調(diào)試內(nèi)存管理問題很令人頭疼。大家都知道震檩,向業(yè)已回收的對(duì)象發(fā)送消息是不安全的琢蛤。這么做有時(shí)可以,有時(shí)不行抛虏。具體可行與否...
    SuperBoy_Timmy閱讀 1,207評(píng)論 1 5
  • 29.理解引用計(jì)數(shù) Objective-C語言使用引用計(jì)數(shù)來管理內(nèi)存博其,也就是說,每個(gè)對(duì)象都有個(gè)可以遞增或遞減的計(jì)數(shù)...
    Code_Ninja閱讀 1,490評(píng)論 1 3
  • 從三月份找實(shí)習(xí)到現(xiàn)在迂猴,面了一些公司慕淡,掛了不少,但最終還是拿到小米沸毁、百度峰髓、阿里傻寂、京東、新浪携兵、CVTE疾掰、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,246評(píng)論 11 349
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法徐紧,內(nèi)部類的語法静檬,繼承相關(guān)的語法,異常的語法并级,線程的語...
    子非魚_t_閱讀 31,631評(píng)論 18 399
  • 盡管會(huì)有很多的遺憾 也絕不能停止前行 因?yàn)橹挥胁粩嗯?才可以更多接近光明
    王根云閱讀 253評(píng)論 0 2