關於objective-c的內存管理,咱們都知道一個原則就是「誰建立,誰釋放」,換句話說,不是咱們建立的,就不用咱們去釋放。可是實際上objective-c的內存管理遠遠沒那麼簡單,個人狀況是這樣的:objective-c
若是場景切換的時候dealloc沒有調用,說明你這個場景的內存有問題。有可能被某個對象retain了,其retainCount在 replaceScene的時候沒有減小到0,因此dealloc方法是不會調用的。若是dealloc方法都沒有調掉,那麼這其實就是一種內存泄露。函數
最後的最後才發現其實是performSelector延時調用的問題,經查找資料,performSelector關於內存管理的執行原理是這 樣的執行 [self performSelector:@selector(method1:) withObject:self.tableLayer afterDelay:3]; 的時候,系統會將tableLayer的引用計數加1,執行完這個方法時,還會將tableLayer的引用計數減1,而在個人遊戲裏這個延時執行函數是 被屢次調用的,有時切換場景時延時函數已經被調用但尚未執行,這時tableLayer的引用計數沒有減小到0,也就致使了切換場景dealloc方法 沒有被調用,出現了內存泄露。orm
因此最後個人解決辦法就是取消那些尚未來得及執行的延時函數,代碼很簡單:對象
[NSObject cancelPreviousPerformRequestsWithTarget:self]遊戲
固然你也能夠一個一個得這樣用:內存
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(method1:) object:nil]get
加上了這個之後,切換場景也就很順利地執行了dealloc方法,至此問題解決!it
最後在找資料時也發現了,延時調用實現長按鈕的實現思路,記錄下來以備後用:內存管理
在touchBegan裏面io
[self performSelector:@selector(longPressMethod:) withObject:nil afterDelay:longPressTime]
而後在end 或cancel裏作判斷,若是時間不夠長按的時間調用:
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(longPressMethod:) object:nil]
取消began裏的方法
最後最後總結:
performSelector是一個頗有用的函數,跟它打過很多交道,通過血與淚的教訓,總結一下它的使用以下:
使用前先檢測一下,
SEL testSelector = @selector(test:);
if([tester respondsToSelector:testSelector])
{
//若是響應就執行
[tester test:@"invoke test method"];
}
使用後,若是有必要,須要顯示的調用cancelPreviousPerformRequestsWithTarget:selector:object: ,不然有可能產生內存泄露,並且這種內存泄露很難發現,由於它並不違反任何規則,因此必定要注意!