当在启用ARC的C代码中执行目标C代码时,运行时内存泄漏警告 [英] Runtime memory leaked warnings when executing objective-C code within C code with ARC enabled
问题描述
ARC已启用, bufferReady
正在由C ++库(非启用ARC)触发,我确定我在某处丢失了ARC。请指教。提前感谢。
使用以下代码:
@implementation HelloWorldLayer
id refToSelf; // reference to self
int shakeCounter = 0;
void bufferReady(){
if(shakeCounter%100 == 0){
[refToSelf shakes];
}
shakeCounter ++;
}
- (void)shakes {
CCRotateBy * rotate = [CCRotateBy actionWithDuration:0.1 angle:2];
CCActionInterval * rotateReverse = [rotate reverse];
CCSequence * seq1 = [CCSequence actions:rotate,rotateReverse,nil];
CCMoveBy * shake = [CCMoveBy actionWithDuration:0.1 position:ccp(5,0)];
CCActionInterval * shakeReverse = [反向抖动];
CCSequence * seq2 = [CCSequence actions:shake,shakeReverse,nil];
CCSpawn * spawner = [CCSpawn actions:seq1,seq2,nil];
CCSequence * lastSequence = [CCSequence actions:spawner,spawner,spawner,spawner,nil];
[self runAction:lastSequence];
}
- (id)init {
if((self = [super init])){
...
} $ b b refToSelf = self;
return self;
}
在运行时我每次收到内存泄漏的警告 $ sh $
objc [10060]:对象0x466830类CCRotateBy自动释放,没有池in objc_autoreleaseNoPool()to debug
objc [10060]:对象0x44cb70的类CCRotateBy自动释放,没有池在适当位置 - 只是泄漏 - 在objc_autoreleaseNoPool()调试
objc [ 10060]:CCSequence类的对象0x46b260自动释放没有池在适当位置 - 只是泄漏 - 在objc_autoreleaseNoPool()调试
objc [10060]:对象0x45a790类CCMoveBy自动释放,没有池 - 恰好泄露 - 中断on objc_autoreleaseNoPool()to debug
objc [10060]:对象0x469150类CCMoveBy自动释放,没有池在适当位置 - 只是泄露 - 在objc_autoreleaseNoPool()调试
objc [10060]:对象0x469190类CCSequence自动释放,没有池在适当位置 - 只是泄漏 - 在objc_autoreleaseNoPool()调试
objc [10060]:对象0x46b350类CCSpawn自动释放,没有池在适当位置 - 只是泄漏 - 在objc_autoreleaseNoPool b $ b objc [10060]:CCSequence类的对象0x46b380自动释放,没有池 - 正好泄露 - 在objc_autoreleaseNoPool()上调用
objc [10060]:自动释放类CCStype的对象0x46b3b0, - 只是泄露 - 在objc_autoreleaseNoPool()调试
objc [10060]:对象0x46bc00类CCSequence自动释放没有池在适当位置 - 只是泄露 - 在objc_autoreleaseNoPool()调试
解决方案您没有错过ARC cast。
我想你的C ++创建一个单独的线程,并调用
bufferReady
在该线程。因为它是一个C ++库,我认为它不知道任何关于Objective-C或Cocoa内存管理,所以它不创建一个自动释放池。因此,应在bufferReady
中创建自动释放池:void bufferReady(){
if(shakeCounter%100 == 0){
@autoreleasepool {
[refToSelf shakes];
}
}
shakeCounter ++;
}
但我还是看到
c $ c>,您正在创建Cocos2D对象并向自己发送
runAction:
,可能是为了运行您创建的操作对象。你确定可以安全地在随机线程上这样做吗?也许你应该发送自己shakes
在主线程。这是一个简单的方法来做到这一点:void bufferReady(){
if(shakeCounter%100 == 0) {
dispatch_async(dispatch_get_main_queue(),^ {
[refToSelf shakes];
});
}
shakeCounter ++;
}
$ b $ p由于主线程管理自己的自动释放池,在这种情况下设置一个。
ARC is enabled and
bufferReady
is being triggered by a C++ library(non-ARC enabled), and I'm sure I'm missing an ARC cast somewhere. Please advise. Thanks in advance.With the code below:
@implementation HelloWorldLayer id refToSelf; //reference to self int shakeCounter = 0; void bufferReady() { if (shakeCounter % 100 == 0) { [refToSelf shakes]; } shakeCounter++; } - (void) shakes { CCRotateBy * rotate = [CCRotateBy actionWithDuration:0.1 angle:2]; CCActionInterval * rotateReverse = [rotate reverse]; CCSequence * seq1 = [CCSequence actions:rotate, rotateReverse, nil]; CCMoveBy * shake = [CCMoveBy actionWithDuration:0.1 position:ccp(5, 0)]; CCActionInterval * shakeReverse = [shake reverse]; CCSequence * seq2 = [CCSequence actions:shake, shakeReverse, nil]; CCSpawn * spawner = [CCSpawn actions:seq1, seq2, nil]; CCSequence * lastSequence = [CCSequence actions:spawner, spawner, spawner, spawner, nil]; [self runAction:lastSequence]; } - (id) init { if((self = [super init])) { ... } refToSelf = self; return self; }
During runtime I'm receiving memory leaked warnings every time
shakes
is executed.objc[10060]: Object 0x466830 of class CCRotateBy autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug objc[10060]: Object 0x44cb70 of class CCRotateBy autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug objc[10060]: Object 0x46b260 of class CCSequence autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug objc[10060]: Object 0x45a790 of class CCMoveBy autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug objc[10060]: Object 0x469150 of class CCMoveBy autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug objc[10060]: Object 0x469190 of class CCSequence autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug objc[10060]: Object 0x46b350 of class CCSpawn autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug objc[10060]: Object 0x46b380 of class CCSequence autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug objc[10060]: Object 0x46b3b0 of class CCSequence autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug objc[10060]: Object 0x46bc00 of class CCSequence autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
解决方案You're not missing an "ARC cast".
I guess your C++ creates a separate thread and calls
bufferReady
on that thread. Since it's a C++ library, I presume it doesn't know anything about Objective-C or Cocoa memory management, so it doesn't create an autorelease pool. Therefore you should create an autorelease pool inbufferReady
:void bufferReady() { if (shakeCounter % 100 == 0) { @autoreleasepool { [refToSelf shakes]; } } shakeCounter++; }
But also I see that in
shakes
, you're creating Cocos2D objects and sendingrunAction:
to yourself, presumably to run the action objects you created. Are you sure it's safe to do this on a random thread? Maybe you should send yourselfshakes
on the main thread. Here's an easy way to do that:void bufferReady() { if (shakeCounter % 100 == 0) { dispatch_async(dispatch_get_main_queue(), ^{ [refToSelf shakes]; }); } shakeCounter++; }
Since the main thread manages its own autorelease pool, you don't have to set one up in this case.
这篇关于当在启用ARC的C代码中执行目标C代码时,运行时内存泄漏警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!