CCCallFuncN误用导致引用计数循环引用
昨天测试“角色被遮挡部分透明显示”功能时,发现角色死亡后,其轮廓精灵不会消失。调试发现,角色在死亡时,其引用计数retain_count居然是9。这是由引用计数混乱引起的内存泄露。
加了很多日志跟踪retain_count,又通过调试,终于确定了问题,是我错误使用CCCallFuncN这个CCAction导致的。于是查看cocos2d-x2.2.1源代码了解这个类的实现原理。
CCCallFuncN是CCAction的子类,是函数回调动作。我在游戏中用这个类来实现“角色死亡后倒地4秒渐渐消失再删除精灵”功能。
PathFinder::_deadAction = CCSequence::createWithTwoActions(
CCFadeOut::create(4.0f),
CCCallFuncN::create(this, callfuncN_selector(PathFinder::callbackDead)));
其中,CCCallFuncN::create的第一个参数this将作为方法PathFinder::callbackDead的参数,CCCallFuncN内部会对其retain一次。
所以,PathFinder的成员引用了PathFinder,其retain_count至少是1,因此永远不会析构,循环引用导致内存泄露。
刚发现这个错误,我愚蠢地在_deadAction创建后面加了一个this->release(),这样日志中retain_count正常了,可是忘了当PathFinder析构时析构_deadAction又会对PathFinder做release()操作,导致retain_count变为负数断言。
改成这样即可,注意runAction时也会retain调用对象,目前还没发现问题:
_deadAction = CCSequence::createWithTwoActions(
CCFadeOut::create(4.0f),
CCRemoveSelf::create());
对于必须要使用CCFunc的函数,建议把该函数放到其他类中。
经验:
1.千万不能让对象持有引用了该对象的成员,特别是精灵create这种隐蔽的情况;
2.精灵create时,可能会retain传入的其他对象,当然我一般不会retain,因为有自己的内存管理规则。
3.析构函数加日志,确保确实析构。
CCCallFuncN误用导致引用计数循环引用的更多相关文章
- 【iOS】自动引用计数 (循环引用)
历史版本 ARC(Automatic Reference Counting,自动引用计数)极大地减少了Cocoa开发中的常见编程错误:retain跟release不匹配.ARC并不会消除对retain ...
- 从urllib2的内存泄露看python的GC python引用计数 对象的引用数 循环引用
这里会发现上述代码是存在内存泄露,造成的原因就是lz与ow这两个变量存在循环引用,Python 不知道按照什么样的安全次序来调用对象的 __del__() 函数,导致对象始终存活在 gc.garbag ...
- nodejs中相互引用(循环引用)的模块分析
话不多少,直接上源码吧: modA.js: module.exports.test = 'A'; const modB = require('./05_modB'); console.log( 'mo ...
- 【转】iOS学习之容易造成循环引用的三种场景
ARC已经出来很久了,自动释放内存的确很方便,但是并非绝对安全绝对不会产生内存泄露.导致iOS对象无法按预期释放的一个无形杀手是——循环引用.循环引用可以简单理解为A引用了B,而B又引用了A,双方都同 ...
- Block循环引用问题研究
自从苹果在objc中添加Block功能支持以后已经过了很久.目前网上对于Block的使用有很多介绍.不过对于Block的内存管理问题,则是众说纷纭.再加上objc开始使用ARC以后,对于Block的内 ...
- 【原】iOS容易造成循环引用的三种场景,就在你我身边!
ARC已经出来很久了,自动释放内存的确很方便,但是并非绝对安全绝对不会产生内存泄露.导致iOS对象无法按预期释放的一个无形杀手是——循环引用.循环引用可以简单理解为A引用了B,而B又引用了A,双方都同 ...
- Swift2.1 语法指南——自动引用计数
原档: https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programm ...
- iOS容易造成循环引用的三种场景
iOS容易造成循环引用的三种场景 ARC已经出来很久了,自动释放内存的确很方便,但是并非绝对安全绝对不会产生内存泄露.导致iOS对象无法按预期释放的一个无形杀手是--循环引用.循环引用可以简单理解为 ...
- swift学习笔记之-自动引用计数
//自动引用计数 import UIKit /*自动引用计数(Automatic Reference Counting) 防止循环强引用 Swift 使用自动引用计数(ARC)机制来跟踪和管理你的应用 ...
随机推荐
- [hackerrank]Palindrome Index
简单题. #include <iostream> #include <string> using namespace std; int main() { int T; cin ...
- python 利用pop3接收邮件并保存附件
def SaveAttach():# login the pop3 server ,retrive the new mails ,and download the attachments dstdir ...
- Spring IoC — 基于XML的配置
1.属性注入 注意点: 1)如果类中显示定义了一个带参的构造函数,则一定还要显示提供一个无参构造函数,否则使用属性注入时将抛出异常. 2)JavaBean关于属性命名的特殊规范.Spring只会检查B ...
- mysql 插入汉字 异常 Incorrect string value: '\xE8\xA7\x84\xE5\x88\x99' for column 'name'
今天使用mysql出现 Incorrect string value: '\xE8\xA7\x84\xE5\x88\x99' for column 'name' 异常 通过查找问题,发现是字段编码不支 ...
- redis sentinel 配置
在最小配置:master.slave各一个节点的情况下,不管是master还是slave down掉一个,“完整的”读/写功能都将受影响,这在生产环境中显然不能接受.幸好redis提供了sentine ...
- Hadoop集群(第7期)_Eclipse开发环境设置
1.Hadoop开发环境简介 1.1 Hadoop集群简介 Java版本:jdk-6u31-linux-i586.bin Linux系统:CentOS6.0 Hadoop版本:hadoop-1.0.0 ...
- ZOJ 3790 Consecutive Blocks (离散化 + 暴力)
题目链接 虽然是一道暴力的题目,但是思路不好想.刚开始还超时,剪枝了以后1200ms,不知道为什么还是这么慢. 题意:给你n个点,每个点有一种颜色ci,给你至多k次删除操作,每次删除一个点,问最多k次 ...
- Android ArrayAdapter 详解
本文主要讲解ArrayAdapter的创建方法,我把ArrayAdapter分为三种:简单的.样式丰富的但内容简单的.内容丰富的. 默认的,ArrayAdapter期望接受的样式文件里只含有一个tex ...
- Deferred的那些知识
在移动开发中的各种中,我们一定会遇到异步回调的问题,比如: 1:Css3执行动画完毕, 回调 2:Jquery Animate动画的执行完毕, 回调 3:Ajax的执行(并行.串行),回调 等等 ...
- BZOJ 2179 FFT快速傅里叶
fft. #include<set> #include<map> #include<ctime> #include<queue> #include< ...