2012-08-07 101 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