蘋果規(guī)定,虛擬商品必須采用內(nèi)購形式購買祷愉。
在接入內(nèi)購過程中窗宦,遇到一個內(nèi)存泄漏問題。如下圖二鳄,
具體操作方式:點擊獲取商品列表頁面赴涵,在商品列表沒有加載完畢時,返回上一級頁面订讼,此時閃退髓窜。報錯如上圖。
解決方式:
分析:在此引入僵尸對象概念欺殿,所謂僵尸對象寄纵,是用于捕捉內(nèi)存錯誤的調(diào)試功能。
通常情況下脖苏,當引用計數(shù)降為0時對象會立即被釋放程拭,但這使調(diào)試變得困難。如果開啟了僵尸對象棍潘,那么對象就不會立即釋放內(nèi)存恃鞋,而是被標記為僵尸。任何試圖對其進行訪問的行為都會被日志記錄亦歉,因而你可以在對象的生命周期中跟蹤對象在代碼中被使用的位置恤浪。
NSZombieEnabled是一個環(huán)境變量,可以控制Core Foundation的運行時是否將使用僵尸對象肴楷。不應長期保留NSZombieEnabled,因為默認情況下是不會有對象被真正析構(gòu)水由,這會導致應用使用大量的內(nèi)存。特別說明:在發(fā)布的構(gòu)建包中一定要禁用NSZombieEnabled赛蔫。
設置NSZombieEnabled環(huán)境變量砂客,需要進入Product->Scheme->Edit Scheme直秆。選擇左側(cè)的Run,然后再右側(cè)選取Diagnostics標簽頁。選中Enable Zombie Objects 選項鞭盟。
設置完成后圾结,報錯如下:
通過日志可以清晰地確認是哪個類發(fā)生了內(nèi)存泄漏。于是齿诉,追蹤到這個類筝野,發(fā)現(xiàn)注冊的通知,在最后dealloc中已經(jīng)移除了粤剧。同時根據(jù)斷點歇竟,發(fā)現(xiàn)在返回上一級后,代理的方法抵恋,還在執(zhí)行焕议。故而想到試著把代理置為nil。
因而最終解決方式是:
SKProductsRequest *request;
- (void)dealloc {
? ? [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
?? ?request.delegate = nil;
}
注:在進行必要清理時一定要移除觀察者(具體來說弧关,移除對通知的注冊)盅安,解除回調(diào)(具體來說,將強引用的委托設置為nil)世囊。