iOS 記憶體洩漏的常見場景

2021-08-19 14:28:25 字數 2420 閱讀 8065

注意以creat,copy作為關鍵字的函式都是需要釋放記憶體的,注意配對使用。比如:cgcolorcreate<-->cgcolorrelease

這部分不做詳細介紹,也是注意配對使用,需要說明的是,如果**中有部分檔案是mrc的,在已有檔案中加**的時候注意一下,不能都按照arc的方式處理。

arc已經為我們做了很多封裝,我們不必再顯示的呼叫retain,release,但是還是要注意迴圈引用的場景。

在此,常規的物件間的互相引用和block的迴圈引用大家都比較了解,這裡就不贅述了,羅列幾個我們**中的錯誤。

1. nstimer

nstimer會造成迴圈引用,timer會強引用target即self,一般self又會持有timer作為屬性,這樣就造成了迴圈引用。

那麼,如果timer只作為區域性變數,不把timer作為屬性呢?同樣釋放不了,因為在加入runloop的操作中,timer被強引用。而timer作為區域性變數,是無法執行invalidate的,所以在timer被invalidate之前,self也就不會被釋放。

所以我們要注意,不僅僅是把timer當作例項變數的時候會造成迴圈引用,只要申請了timer,加入了runloop,並且target是self,雖然不是迴圈引用,但是self卻沒有釋放的時機。如下方式申請的定時器,self已經無法釋放了。

nstimer *timer = [nstimer timerwithtimeinterval:5 target:self selector:@selector(commentanimation) userinfo:nil repeats:yes];

[[nsrunloop currentrunloop] addtimer:timer formode:nsrunloopcommonmodes];

每次任務結束時使用dispatch_after方法做延時操作。注意使用weakself,否則也會強引用self。

- (void)startanimation

);}

ws(weakself);

timer = dispatch_source_create(dispatch_source_type_timer, 0, 0, dispatch_get_main_queue());

dispatch_source_set_timer(timer, dispatch_time_now, 5 * nsec_per_sec, 1 * nsec_per_sec);

dispatch_source_set_event_handler(timer, ^);

dispatch_resume(timer);

2. nsnotification

使用block的方式增加notification,引用了self,在刪除notification之前,self不會被釋放,與timer的場景類似,其實這段**已經宣告了weakself,但是呼叫_eventmanger方法還是引起了迴圈引用。

也就是說,即使我們沒有呼叫self方法,_***也會造成迴圈引用。

[[nsnotificationcenter defaultcenter] addobserverforname:kusersubscribenotification object:nil queue:nil usingblock:^(nsnotification *note) 

}}

3. __block

__blockmrc中是不會增加引用的,可是在arc中會增加,所以在arc中,只能使用__weak去打破迴圈引用。

__block myviewcontroller *weaksef = self;

_myviewcontroller.editblock = ^();

另外宣告一點,並非所有的block都需要使用weak來打破迴圈引用,如果self沒有持有block就不會造成迴圈引用(例如, 動畫block塊)。而有些地方之所以使用了__weak,是為了在[self dealloc]之後就不再執行了。在這種場景下使用weakself時,也需要注意,如果self被釋放了會不會引起異常。比如下面這段**把weakself取到的值作為入參,如果self釋放了,傳nil,引起crash:

iOS 記憶體洩漏的常見場景

注意以create,copy作為關鍵字的函式都是需要釋放記憶體的,注意配對使用。比如 cgcolorcreate cgcolorrelease 這部分不做詳細介紹,也是注意配對使用,需要說明的是,如果 中有部分檔案是mrc的,在已有檔案中加 的時候注意一下,不能都按照arc的方式處理。arc已經為我...

Golang 記憶體洩漏場景

雖然golang 的runtime 會 記憶體,但是本文列舉的場景仍然會造成記憶體洩漏。todo 此處需要了解下golang 的底層 memory block 分配知識 var s0 string 包級別變數 a demo purpose function.func f s1 string func...

常見的記憶體洩漏

vector v new vector 10 for int i 1 i 100 i 如果我們僅僅釋放引用本身,那麼 vector 仍然引用該物件,所以這個物件對 gc 來說是不可 的。因此,如果物件加入到vector 後,還必須從 vector 中刪除,最簡單的方法就是將 vector 物件設定為...