今天在真機調試的過程中,發現了一個嚴重的問題,發現CPU的使用率竟然達到了100%,以至於會導致運行內存占用過高,被系統的看門狗機制給殺掉。
下面就講一講怎么去定位這個問題:
1.打開Xcode,把項目跑動起來,然后選擇這個選項卡
2.現在就可以看到這個畫面
3. 現在我們可以看到這個頁面,發現我的CPU達到了 105%,這肯定是有問題,那現在怎么辦呢,我們可以看到右邊的圖,點擊Profile in Instruments. ---》 然后點擊Transfer.
4. 現在就進入到Instruments中,我們看看究竟發生了什么,到底是什么情況,導致出現了這種問題。
1. 首先,我通過觀察CPU占用率,各個頁面進行排查,看是進行了何種操作后,才出現的這種CPU占用率居高不小。
2. 我很慶幸,我很快就定位到了原因。所以我可以知道是進入某一個頁面,觸發了某種操作后,然后,就會出現這種情況
3. 現在就可以通過Instruments來進行定位,來看看是執行什么代碼,導致了這種非常耗時的操作,讓CPU一直如此忙碌。
4.選中Xcode先把程序(command + R)運行起來
5.再選中Xcode,按快捷鍵(command + control + i)運行起來,此時Leaks已經跑起來了
6.由於Leaks是動態監測,所以我們需要手動操作APP,一邊操作,一邊觀察Leaks的變化,當出現紅色叉時,就監測到了內存泄露,點擊右上角的第二個,進行暫停檢測(也可繼續檢測,當多個時暫停,一次處理了多個).
擴展: 查內存泄露具體方法 點擊打開鏈接l
5. 電腦卡爆了,哎。 回去了在截圖,反正最后是跟蹤到了 Runloop下。 有一個行為一直在占據着主線程,並且不釋放,所以導致CPU一直在大量消耗,內存也慢慢漸長,一般能造成這種情況的就只有循環,並且一直沒有釋放,我利用Instruments中的leaks,然后進行了各種各樣的內存泄露的檢測及修復, 也正是這樣,我發現了問題的所在。 原來是我寫的有一個方法有問題。 我寫的代碼如下:
我們很清晰的看到如果條件為真,這就是一個死循環,我的PM那時候,這兒就想做一個圖片一直閃爍的效果,這兒可以采用三種方案,一種是用這種循環引用來執行一套方法, 一種是通過NSTimer來定時去調用一個方法。我開始選擇了前者,那時候也知道后果,也許這個死循環會一直存在下去,直到這個VC被dealloc,最后一種是通過 core animation來實現。 這種事最推薦的,具體寫法,我會在后面開博客進行講解
- -(void)animationAction:(bool)isNeedbreak{
- if(!isNeedbreak) {
- [self performSelector:@selector(animationAction:) withObject: [NSNumber numberWithBool:YES] afterDelay:2];
- }
- }
2. 由於有上面這個擔心所以,我在popviewcontroller, 控制器出棧的時候,我調用了如下方法,那個時候太粗心了,大概比方,是我想延遲2s執行一個方法,這個過程中,我想終止方法,那就只有通過調用下面兩種隨意一種,我卻很天真的以為,這樣就可以完美的終止死循環的調用。
- //這個是取消所有的延遲執行函數。
- [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(animationAction:) object:[NSNumber numberWithBool:YES]];
- [NSObject cancelPreviousPerformRequestsWithTarget:self];
3. 發現問題依然存在,所以只能用我的第二種解決辦法, 用NSTimer來代替他。代碼如下
- NSTimer *animationTwoTime = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(productBrandIconAnimationWithIsBreak:) userInfo:[NSNumber numberWithBool:NO] repeats:YES];
4. 然后在vc出棧的時候,然后把NSTimer進行 invalidate下。
總結:
1.以后一定要慎用用for循環來進行實現動畫的連續執行.
2. 這種動畫效果盡量用 core animation來進行解決。