Подъем понимания: использование памяти & утечки
Помогая другим решить их проблемы проекта cocos2d за прошлый год стало очевидно, что у многих проектов есть по крайней мере одна большая проблема в одной из этих областей:
- управление памятью
- управление ресурсом
- кодовая структура
Примеры
Управленческие проблемы памяти обычно колеблются от распределения слишком большой памяти, или загружая слишком много структур фронт, которые только собираются быть необходимыми позже, или утечками памяти, такими как сцены, не освобождающие, переключая сцены. Проблемы управления ресурса располагаются от не добавления правильных ресурсов к правильной цели, часто приводящей к увеличенному размеру Приложения, потому что ресурсы добавлены к связке, но никогда не используются Приложением. Это могло также означать загружать идентичные файлы ресурса за исключением того, что у них есть различные имена файла (копии?), израсходовав дополнительную память. Или не плотно упаковывающие вещи эльфы в Атласы Структуры, но вместо этого использование одного Атласа Структуры за объект игры – в то время как это понятно с точки зрения логического seperation, он действительно тратит впустую возможности для оптимизации. It could also mean loading identical resource files except that they have different filenames (copies?), using up additional memory. Or not tightly packing sprites into Texture Atlases but instead using one Texture Atlas per game object – while this is understandable from a standpoint of logical seperation it does waste opportunities for optimization.
Наконец, кодовая структура или нехватка этого регулярно приводят “ко всему в одном классе” кодовый дизайн, который является наиболее вероятным эволюционный процесс, а не намеренным. Весьма распространено видеть классы с тысячами линий кодекса, иногда даже идущие прошлые 10 000 линий кодекса в одном классе. Другие вещи используют слишком много CCLayers без них добавляющий ясную выгоду, например только, чтобы сгруппировать все узлы в определенном заказе z вместе или сгруппировать их функциональностью, eg один слой для врагов, один для игроков, один для фона, один для UI, один для счета, один для эффектов частицы, и так далее – без любого из этих слоев, используемых для того, в чем они действительно хороши: изменение многократных узлов сразу, как перемещение, вычисление, вращение или z-переупорядочение их. И конечно есть копия & паста черт, большие блоки программы, воспроизведенные в различных местах только, чтобы изменить некоторые параметры вместо того, чтобы создать метод, который берет поддающиеся изменению параметры в качестве аргументов. Даже профессионалы, я работал со ставшимся, столь привыкшим к выполнению, что стало трудно только преодолеть сопротивление того, чтобы отпускать старых привычек. Но они учились. Other things are using too many CCLayers without them adding a clear benefit, for example just to group all nodes at a specific z order together or to group them by functionality, eg one layer for enemies, one for players, one for background, one for UI, one for score, one for particle effects, and so on – without any of these layers being used for what they’re really good at: modifying multiple nodes at once, like moving, scaling, rotating or z-reordering them. And of course there’s the copy & paste hell, large blocks of code reproduced in various places only to modify some parameters instead of creating a method which takes the modifiable parameters as arguments. Even professionals I worked with got so used to doing that it became hard just to overcome the resistance of letting go of old habits. But they learned.
Резюме
Ничто из этого кодового дизайна и структурирования не кажется мне странный или удивительный. Я написал кодекс как это непосредственно. Я также верю, достаточно хорошо ли это и работы, тогда какого черта нет? Это - вопрос опыта, и только с опытом Вы ясно видите, как улучшить вещи. Это сводится к регулярной кривой обучения, где только обучение и обучение и просто делание ошибок и изучение от них помогают в конечном счете. Это - то, как мы изучаем вещи. I also believe if it’s good enough and works, then why the hell not? It’s a matter of experience and it’s only with experience that you clearly see how to improve things. This boils down to the regular learning curve where only training and tutoring and just simply making mistakes and learning from them helps in the long run. That’s how we learn things.
С другой стороны вещи как управление Памятью и Ресурсом могут также быть выучены лишь, у них есть различная природа. Они могут быть статистически оценены, они могли быть вычислены и проверены автоматически. Это заставляет меня задаться вопросом, нет ли некоторых инструментов автоматизации и информации, которые помогли бы разработчикам достигнуть лучших результатов с точки зрения использования памяти и управления ресурсом? Тем временем это - все о подъеме понимания … This makes me wonder if there isn’t some kind of automation and information tools that would help developers achieve better results in terms of memory usage and resource management? In the meantime it’s all about raising awareness …
Подъем Понимания Памяти
Что наиболее важно я думаю, что мы должны поднять больше понимания до этих проблем cocos2d разработчикам. Один шаг к этому был бы для cocos2d, чтобы показать “доступный прилавок памяти” рядом с прилавком FPS. Я имел обыкновение исправлять CCDirector, чтобы просто показать память вместо FPS, так как это было всегда более важным для меня. Товарищ cocos2d разработчик Джозеф послал мне свою версию, чтобы показать обоих – я просто не думал об очевидном. Так, если Вы хотели бы видеть FPS и доступную память друг рядом с другом, я думаю, что Вы можете обращаться с изменениями CCDirector, обрисованного в общих чертах здесь: I used to patch CCDirector to simply display memory instead of FPS since that was always more important to me. Fellow cocos2d developer Joseph sent me his version to display both – I simply didn’t think of the obvious. So if you’d like to see FPS and available memory next to each other I think you can handle the changes to CCDirector outlined here:
//CCDirector.h, добавляют ниже @interface: + (двойной) getAvailableBytes; + (двойной) getAvailableKiloBytes; + (двойной) getAvailableMegaBytes; //CCDirector.m, добавляют как соответствующий: #include <sys/sysctl.h> #import <mach/mach.h> #import <mach/mach_host.h> [...] + (двойной) getAvailableBytes { vm_statistics_data_t vmStats; mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT; kern_return_t kernReturn = host_statistics (mach_host_self (), HOST_VM_INFO, (host_info_t)&vmStats, &infoCount); если (kernReturn! = KERN_SUCCESS) { возвратите NSNotFound; } возвратитесь (vm_page_size * vmStats.free_count); } + (двойной) getAvailableKiloBytes { возвратитесь [CCDirector getAvailableBytes] / 1024.0; } + (двойной) getAvailableMegaBytes { возвратитесь [CCDirector getAvailableKiloBytes] / 1024.0; } [...] - (пустота) showFPS { структуры ++; accumDt + = dt; если (accumDt> CC_DIRECTOR_FPS_INTERVAL) { frameRate = frames/accumDt; структуры = 0; accumDt = 0; //единственное изменение в showFPS - эта линия: NSString *str = [[NSString alloc] initWithFormat:@" %.1f %.1f", frameRate, [CCDirector getAvailableMegaBytes]]; [FPSLabel setString:str]; [выпуск str]; } }
Подъем понимания к протекающим Сценам
Кроме того, я чрезвычайно, сильно и с предельным укреплением (не вытаскивая оружие) рекомендую cocos2d разработчикам часто проверить dealloc методы Вашей сцены. Предпочтительно добавьте контрольную точку там, или по крайней мере добавьте линию заготовки леса: CCLOG (”dealloc: %”, сам). Если Вы хотите более видимый, но менее навязчивый метод, Вы могли бы сделать что-то как высвечивание экрана или игра звука всякий раз, когда последняя сцена освобождена, так, чтобы Вы стали настолько привыкшими к этому, что, когда Вы не видите или слышите это больше, это немедленно поднимает Ваше внимание. CCLOG(@”dealloc: %@”, self). If you want a more visible but less intrusive method you could do something like flashing the screen or playing a sound whenever the last scene is deallocated, so that you get so used to it that when you’re not seeing or hearing it anymore it immediately raises your attention.
Если когда-либо во время развития Вашего проекта dealloc метод сцены не называют, когда Вы изменяете сцены, Вы пропускаете память. Утечка целой сцены является утечкой памяти худшего вида. Вы хотите поймать это рано, в то время как Вы можете все еще восстановить свои шаги, которые, возможно, вызвали проблему. Как только Вы добираетесь до использования сотен активов и тысяч линий кодекса и затем понимаете, что сцена не освобождена, Вы будете в для забавной поездки, пытающейся выяснять, куда это прибывает из. В этом случае удаление узлов, некомментируя их, пока Вы не можете приблизиться к преступнику, является, вероятно, лучшей стратегией, рядом с использованием Инструментов (который я не счел слишком полезным в тех случаях). You want to catch that early while you can still retrace your steps that might have caused the problem. Once you get to using hundreds of assets and thousands of lines of code and then realize the scene isn’t deallocated, you’ll be in for a fun ride trying to figure out where that’s coming from. In that case, removing nodes by uncommenting them until you can close in on the culprit is probably the best strategy, next to using Instruments (which I haven’t found too helpful in those cases).
Я столкнулся с такой проблемой как, потому что я передавал объект CCScene к подклассам так, чтобы у них был доступ к методам сцены. Подкласс сохранил сцену и был самостоятельно получен из CCNode и добавил к CCScene как ребенок. Проблема с этим: во время уборки сцены это правильно удалило все детские узлы, но некоторые из детских узлов все еще сохранили сцену. Из-за этого их dealloc метод никогда не называли, и в свою очередь сцена никогда не освобождалась. The problem with that: during cleanup of the scene it correctly removed all child nodes but some of the child nodes still retained the scene. Because of that their dealloc method was never called, and in turn the scene was never deallocated.
Книга cocos2d, Глава 3: Основы
Глава 3 – Основы
Эта глава - ссылка о фундаментальных классах cocos2d и как использовать их. Узлы, Слои, Сцены, Лейблы, Эльфы, Переходы, Действия, Вы называете это. Также CCDirector, SimpleAudioEngine и другие часто используемые классы единичного предмета также. Более продвинутые понятия будут обсуждены в более поздней главе, Spritesheets например. Also CCDirector, SimpleAudioEngine and other often used singleton classes as well. More advanced concepts will be discussed in a later chapter, Spritesheets for example.
Подчинение первого проекта главы должно следующий пятница, 16-ого июля.
То, что делает Вы думаете, должно быть в Главе 3?
Вы знаете cocos2d класс или процесс, что Вы думаете, важно и должен быть обсужден в этой главе? Сообщите мне!
Резюме работы над Главой 2 – Начинание
Для одного я детализировал Привет Мировой типовой проект и сделал простую модификацию, используя вход прикосновения. В то же самое время, по крайней мере, некоторый базовый уровень понимания о cocos2d классах был введен, но суть этого сделана в Главе 3. Кроме того, было много теоретических аспектов, которые я хотел обсудить также, больше всего управление Памятью и доступная память так же как ожидания урегулирования при тестировании на Тренажере против устройства. И конечно устройства и их тонкие различия. Я действительно надеюсь, что подобные детали ценятся, даже если они не 100 %, связанных с cocos2d. Я регулярно вижу, что cocos2d разработчики борются с проблемами памяти с неожиданными различиями на устройстве против Тренажера, или сравнивают framerates Тренажера, и возможно даже Отладка строит. Это заставило меня хотеть отклониться в глуши на мгновение, чтобы, мы надеемся, спасти читателей некоторые неправильные представления и боль, связанная с ними. In addition, there were a lot of theoretical aspects I wanted to discuss as well, most of all Memory Management and available memory as well as setting expectations on testing on Simulator vs. a device. And of course the devices and their subtle differences. I do hope that those kind of details are appreciated even if they’re not 100% related to cocos2d. I regularly see cocos2d developers struggling with memory issues, with unexpected differences on the device vs the Simulator, or comparing framerates of the Simulator and possibly even Debug builds. That made me want to stray off the beaten path for a moment to hopefully save the readers some misconceptions and the pain associated with them.
Я также понял, сколько шагов новый разработчик должен пройти и насколько там должен учиться в случае, если Вы никогда не работали с iPhone SDK прежде. Это начинается с регистрации как разработчик iPhone и не заканчивается монтажом SDK, потому что Вы также нуждаетесь в обеспечивающих профилях, очень обсужденной и неприятной особенности. Для всего этого я отсылал к существующему (и превосходный) документацию Apple. Как правило изменение процессов с каждым новым iPhone, SDK или может даже находиться под NDA, таким образом обсуждая, как все это работает с iPhone SDK 4, не было бы хорошей идеей, так как вскоре после того, как книги отсутствует iPhone, SDK 5 может прибывать, вводя изменения Двери Разработчика и iTunes Соединяется с этим. Это действительно получало меня идея, и я знаю, что у других есть это также, что мы нуждаемся в некоторой Обучающей программе рук холдинга, которая берет один через шаги от регистрации как Разработчик iPhone к публикации первого Приложения, ссылаясь на правильную официальную документацию для каждого шага, не забывая о распространенных ошибках, которые не находятся в официальных докторах. For all of this I refered to existing (and excellent) Apple documentation. Typically the processes change with each new iPhone SDK or may even be under NDA, so discussing how all of this works with iPhone SDK 4 wouldn’t be a good idea since shortly after the book is out iPhone SDK 5 may be coming, introducing changes to the Developer Portal and iTunes Connect with it. It did get me the idea, and I know others have it too, that we need some holding-hands Tutorial which takes one through the steps from registering as iPhone Developer to publishing one’s first App, by referring to the correct official documentation for each step while not forgetting about common pitfalls that are not in the official docs.
Я также заметил, насколько легкий это может быть должно пропустить, как Вы внезапно вводите новое понятие, не объясняя это сначала. И затем Вы должны решить, сколько информации необходимо, чтобы ввести понятие, не отклоняясь слишком далеко от того, о чем Вы хотите говорить во-первых. Это особенно твердо для меня, потому что я склонен хотеть объяснить все подробно, но некоторые вещи должны быть оставлены для более позднего обсуждения. Я с нетерпением жду редакционной обратной связи теперь. Это помогло tremendeously для первой главы, и я учился много из редакции Apress, таким образом, я считаю это возбуждением, что эксперты указывают мне на недостатки и делают предложения, я вхожу, чтобы установить их и затем видеть, насколько лучше это. Это - то, как мне нравится изучать вещи, и это собирается быть одним из основного понятия книги. Покажите, как это сделано, как это не должно быть сделано (если это часто делало неправильно), и как это может быть сделано еще лучше, если Вы хотите избежать проблемы в конечном счете, объясняя почему. It’s especially hard for me because I tend to want to explain everything in detail but some things have to be left for a later discussion. I’m looking forward to editorial feedback now. It has helped tremendeously for the first chapter and I learned a lot from the Apress editorial staff, so I find it exciting that the experts point me to the flaws and make suggestions, I go in to fix them and then see how much better it is. That’s how I like to learn things and it’s going to be one of the core concepts of the book. Show how it’s done, how it shouldn’t be done (if it’s often done wrong) and how it can be done even better if you want to avoid trouble in the long run, while explaining why.










