关于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: ,不然有可能产生内存泄露,并且这种内存泄露很难发现,由于它并不违反任何规则,因此必定要注意!