2013-09-04 2 views
2

Я работаю с ARC и Cocos2d 2.0 как статическую библиотеку (которая не использует ARC и скомпилирована как отдельная цель). Я перевел старый проект (сделанный без ARC), и мне интересно, есть ли объявляя свойства таким образом некоторый потенциал сохранить выпуск цикла:Свойства и ARC

@interface PlayerData : NSObject <NSCoding> { 
} 


//Is ok to save this as if the game gets paused you may want to save this. 
@property (readwrite, nonatomic) int numberOfHits; 
@property (readwrite, nonatomic) bool everBeenHitInCurrentLevel; 
@property (readwrite, nonatomic) int hitsForOneHearth; 

Я заметил, что мои различные сцены наращивать память с течением времени. Также я добавил вызов CCLOG в методе release метода CCLayer (MyScene: CCLayer), и он никогда не вызывается. Вот как я создаю сцену (который я заменю с помощью метода «[CCDirector sharedDirector] replaceScene»

+ (id) sceneWithLevelName:(LevelName)name 
{ 
    CCScene *scene = [CCScene node];   
    ShooterScene * shooterLayer = [[self alloc] initWithId:name]; 
    [scene addChild:shooterLayer]; 


    return scene;  
} 

EDIT: Как я понял, что я тупо не включен пример с объектами, и используется только примитивный тип данных Я здесь вставить некоторые фрагменты элементов в моих сценах: CharacterSelection, ShooterScene и PlanetSelectionMenu:

//ShooterScene 
@interface ShooterScene : CCLayer { 
    HudLayer * hudLayer; 
    .... 
} 

@property(readwrite, nonatomic) CCSpriteBatchNode* backgroundAndEnemiesBatchNode; 
@property(readwrite, nonatomic) ShipEntity* playerShip; 
... etc.. 


Please note that I do not declare member variables for properties like playerShip and backgroundAndEnemiesBatchNode beause, as far as I can understand, should suffice the property declaration (but please correct me if I am wrong or if the approach may cause issues). 

//CharacterSelectionScene 
@interface CharacterSelectionScene : CCLayer { 
    int currentlySelectedCharacterSpriteTag; 
    CCSprite * lights; 
    CCLayer * spritesLayer;  
    ... 
} 

//PlanetSelectionMenu 
#import <Foundation/Foundation.h> 
#import "cocos2d.h" 

@interface PlanetSelectionMenu : CCLayer { 
    CCLayer * backgroundLayer; // Added background images here 
    CCLayer * alwaysPresentItems; 
} 

+ (id) scene; 

@end 

Обратите внимание, что каждый раз, когда я иду от PlanetSelectionMenu в CharacterSelectionSc ene - и наоборот - воспоминания увеличиваются. Однако в этом случае я не использовал никаких свойств, кроме «просто» добавленных объектов (CCSprites) для слоев и batchnodes.

EDIT 2: Вот что я вижу в распределении при работе через Menu-> CharacterSelection-> PlanetSelectionScene и т. Д. Кажется, что в avarage LiveBytes составляет 4 МБ, и, поскольку я вижу только одну сцену в то время, я предполагаю что нет циклов удержания. Тогда почему я получаю эти неприятные сообщения памяти LOW?

enter image description here

+5

Стандартные C-языка типов данных число (INT, BOOL, двойной и т.д.) не может создать сохранить цикл, потому что они не указывают на что-нибудь. Если вы ожидаете, что объект будет освобожден, и это не так, у вас, вероятно, есть другой объект с сильным указателем на него. Какие объекты имеют сильные указатели на «MyScene»? Как вы думаете, они должны освободиться? –

+0

@AaronBrager хорошо пункт. Я добавил лучший пример, включая объекты, а не примитивные типы данных. Я имею в виду CCLayer PlanetSelectionMenu (который на самом деле представляет собой ошибочное имя сцены) и CharacterSelectionScene as, при вызове replaceScene метод dealloc не печатает заявление CCLOG, которое я добавил. – mm24

ответ

6

Хотя атрибут свойство по умолчанию теперь strong, он не может быть те свойства, которые являются причиной сохранения цикла, как те примитивные типы и по умолчанию будет assign

Три других распространенных методов вводящие циклы удержания в голову:

  • Вы реализуете шаблон делегата в любом месте (@protocol). Всегда ли ваши делегаты являются слабыми рекомендациями?
 
    -(id) initWithDelegate:(id) target 
    { 
     ... 
     _target = target; //_target should be a weak reference 
     ... 
    } 
  • ли какие-либо из ваших детей узлов ссылки на своих родителей?
 
    -(id) initWithParent:(CCNode*) parentNode 
    { 
     ... 
     _parent = parentNode; //_parent should be a weak reference. 
     ... 
    } 
  • ли какие-либо блоки ссылки self
 
    ^{[self callSomeMethod];} 

следует использовать слабую ссылку на self:

 
    __weak typeof(self) selfReference = self; 
    ^{[selfReference callSomeMethod];} 

Обычно я обнаружил, что лучший способ найти утечки с помощью ARC - это НЕ использовать инструмент «Утечки», но инструмент «Распределения». Поскольку у всех моих сцен есть слово «сцена» в их символе, я фильтрую сцену слов.

Поскольку вы используете replaceScene, у вас должна быть только одна живая сцена за один раз (за исключением перехода), поэтому вы должны видеть только один объект в сводке объектов.

enter image description here

Если у вас есть сцена, которая висит вокруг, я обычно нахожу, что лучше смотреть на объекты, которые сохраняют историю. Отсюда я соединяю каждого из них с соответствующим выпуском, пока не найду преступника (ов), которые сохраняют и не отпускают мою сцену. Чаще всего это не очевидный цикл сохранения с блоком или свойство, объявленное сильным, а не слабым.

enter image description here

+0

спасибо за подробный ответ. Я применил фильтр сцены в инструменте выделения и, к счастью, в то время была только одна сцена. Однако, когда я смотрю на живые байты, происходит что-то странное. Несмотря на то, что байты составляют около 4/5 МБ при авариях с пиками 18 МБ, когда выделена определенная сцена, я получаю предупреждения о низкой памяти ТОЛЬКО, когда у меня есть выделение 4/5 МБ. Я добавлю фотографию на свой вопрос, чтобы вы могли понять, что я имею в виду. Я также добавил печать доступной памяти в методе предупреждения памяти AppDelegate didReceive, но ничего не было напечатано. – mm24

+0

Хорошо. Я ухожу из Инструменты, и я получаю предупреждения о низком уровне. Первый с 48 МБ, а затем, заменяя сцену после сцены, он создает до 66 МБ, а затем сработает. Странно, что инструмент распределения не показывает этого. – mm24

Смежные вопросы