2012-08-07 51 views
1

启用了ARC并且bufferReady正在由C++库(启用非ARC)触发,并且我确定我缺少ARC演员表某处。请指教。提前致谢。在启用ARC的C代码中执行Objective-C代码时,运行时内存泄露警告

与下面的代码:

@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; 
} 

在运行时我收到内存泄漏的警告,每次执行shakes时间。

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 

回答

2

您不会错过“ARC演员”。

我想你的C++创建一个单独的线程,并在该线程上调用bufferReady。由于它是一个C++库,我认为它不知道任何关于Objective-C或Cocoa内存管理的内容,所以它不会创建一个autorelease池。因此应该bufferReady创建一个自动释放池:

void bufferReady() { 
    if (shakeCounter % 100 == 0) { 
     @autoreleasepool { 
      [refToSelf shakes]; 
     } 
    } 

    shakeCounter++; 
} 

但我也看到,在shakes,你创建的Cocos2D对象和发送runAction:给自己,想必运行的操作对象创建。你确定可以安全地在随机线程上执行此操作吗?也许你应该在主线上发送自己shakes。这里有一个简单的方法来做到这一点:

void bufferReady() { 
    if (shakeCounter % 100 == 0) { 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [refToSelf shakes]; 
     }); 
    } 

    shakeCounter++; 
} 

由于主线程管理自己的自动释放池,你不必设置一个在这种情况下。

+0

你是男人!我显然没有完全掌握ARC和内存管理。你有什么阅读建议吗? – docchang 2012-08-07 07:29:58

+0

内存管理:从* [Cocoa Core能力:内存管理]开始(http://developer.apple.com/library/IOs/#documentation/General/Conceptual/DevPedia-CocoaCore/MemoryManagement.html#//apple_ref/doc/UID/TP40008195-CH27-SW1)*。自动释放池和线程:* [高级内存管理编程指南:使用自动释放池块](https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html)*。 – 2012-08-07 07:34:49

+0

ARC:* [过渡到ARC发行说明](http://developer.apple.com/library/mac/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html#//apple_ref/doc/uid/TP40011226 )*。 – 2012-08-07 07:35:10