Ho bisogno d'aiuto. Ho colliso con problemi strani con cocos2d molto semplice v0.99.4 il progetto creato della sagoma di progetto di cocos2d. Sono due scene con uno strato ciascuno, molto come lo strato HelloWorldScene regolare. Semplicemente si suppone che ogni scena si sostituisca con l'altra scena, su contatto. Quello che avviene è che la prima scena iniziata da runWithScene è mai deallocated dopo il primo cambiamento di scena. Allora rimane in memoria e continua a ricevere i contatti, il que significa che un contatto si sta sempre comportando come se cambiando dal primo alla seconda scena. It’s two scenes with a layer each, much like the regular HelloWorldScene layer. Each scene is simply supposed to replace itself with the other scene, on touch. What happens is that the first scene started with runWithScene is never deallocated after the first scene change. So it stays in memory and keeps receiving the touches, which means a touch is always behaving as if switching from the first to the second scene.
Quello che è più, se aggiungo l'onEnter e i metodi onEnterTransitionDidFinish alla prima scena, senza aggiungergli qualche codice, la prima scena/strato non riceve nessun avvenimento di contatto affatto. La seconda scena non mostra questo comportamento e lavori eccellenti con questi metodi attuati.
Forse sto soltanto guardando il molto ovvio dall'alto, se Lei poteva guardare e fatemi sapere se c'è qualcosa che sto facendo in modo sbagliato con questo codice per favore fatemi sapere! Grazie.
Scarichi il codice qui: ScenesAndLayers02
Sollevamento di coscienza: uso di memoria & perdite
Aiutando altri a risolvere i loro problemi di progetto di cocos2d durante l'anno passato diventò ovvio che molti progetti hanno almeno un gran problema in una di queste aree:
- direzione di memoria
- direzione di risorsa
- struttura di codice
Esempi
I problemi di direzione di memoria normalmente variano da assegnare troppa memoria, caricando troppe strutture sul fronte che solo stanno per essere necessari più tardi, o da perdite di memoria come scene non deallocating cambiando scene. La gamma di problemi di direzione di risorsa da non aggiungere le risorse giuste all'obiettivo giusto, spesso avendo come conseguenza aumentò dimensioni App perché le risorse sono aggiunte al fascio, ma mai usate dall'App. Questo poteva anche intendere caricare file di risorsa identici salvo che loro hanno nomi di file diversi (le copie?), esaurendo la memoria supplementare. O non i folletti strettamente facenti i bagagli in Atlanti di Struttura ma invece utilizzazione di un Atlante di Struttura per oggetto di gioco – mentre questo è comprensibile da un luogo di osservazione di seperation logico proprio spreca opportunità per ottimizzazione. 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.
Finalmente, la struttura di codice o la mancanza di ciò regolarmente conducono “a tutto in una classe” il progetto di codice che è il più probabile un processo evolutivo, piuttosto che intenzionale. È abbastanza comune vedere classi con migliaia di linee di codice, qualche volta perfino 10 000 linee passate andanti di codice in una classe. Altre cose stanno usando troppi CCLayers senza loro aggiungendo un vantaggio chiaro, ad esempio soltanto per raggruppare tutti i nodi a un ordine di z specifico insieme o raggrupparli da funzionalità, eg uno strato per nemici, un per giocatori, un per sfondo, un per UI, un per punteggio, un per effetti di particella, e così via – senza alcuno di questi strati usati per che loro sono veramente bravi: la modificazione di nodi multipli subito, come movimento, scalata, rotazione o z-riordinamento loro. E certamente ci sono l'inferno di pasta & di copia, i grandi blocchi di codice riprodotto in vari posti solo per modificare alcuni parametri invece creare un metodo che prende i parametri modificabili come argomenti. Perfino i professionisti che feci lavorare con ricevuto così solito di fare che diventò duro soltanto vincere la resistenza d'affitto vanno d'abitudini vecchie. Ma loro impararono. 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.
Riassunto
Niente di questo progetto di codice e strutturazione mi sembra strano o sorprendente. Ho scritto il codice come questo io stesso. Anche credo se è abbastanza buono e i lavori, allora perché diavolo no? È una questione d'esperienza e è solo con esperienza che Lei chiaramente vede come migliorare cose. Questo si riduce alla curva d'erudizione regolare dove solo la formazione professionale e l'istruzione e soltanto semplicemente la fabbricazione di sbagli e l'erudizione di loro aiutano nella corsa lunga. Questo è come impariamo cose. 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.
D'altra parte, le cose come direzione di Risorsa e di Memoria possono anche esser imparate ma loro hanno una natura diversa. Loro possono esser statisticamente valutati, loro potevano esser calcolati e verificati automaticamente. Questo mi fa chiedermi se non ci sono i dei certi attrezzi d'informazione e d'automazione che aiuterebbero progettisti a portare a termine risultati migliori in termini d'uso di memoria e direzione di risorsa? Nel frattempo è tutto su sollevamento di coscienza … 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 …
Sollevamento di Coscienza di Memoria
Il più significativamente penso che abbiamo bisogno di alzare più coscienza a questi problemi a progettisti cocos2d. Un passo verso questo sarebbe per cocos2d per esporre un “banco di memoria disponibile” di fianco al banco di FPS. Avevo l'abitudine di rattoppare CCDirector per esporre semplicemente la memoria invece di FPS poiché fu sempre più importante per me. Il compagno cocos2d il progettista Joseph mi mandò la sua versione per esporre entrambi – semplicemente non ho pensato all'ovvio. Così se Le piacerebbe vedere FPS e memoria disponibile vicino all'un l'altro penso che Lei può toccare i cambiamenti a CCDirector abbozzato qui: 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, aggiungono sotto @interface: + getAvailableBytes (doppio); + getAvailableKiloBytes (doppio); + getAvailableMegaBytes (doppio); //CCDirector.m, aggiungono come adatto: #include <sys/sysctl.h> #import <mach/mach.h> #import <mach/mach_host.h> [...] + getAvailableBytes (doppio) { vm_statistics_data_t vmStats; il mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT; il kern_return_t kernReturn = host_statistics (mach_host_self (), HOST_VM_INFO, (host_info_t)&vmStats, &infoCount); se (kernReturn! = KERN_SUCCESS) { restituisca NSNotFound; } ritorni (vm_page_size * vmStats.free_count); } + getAvailableKiloBytes (doppio) { ritorni [CCDirector getAvailableBytes] / 1024.0; } + getAvailableMegaBytes (doppio) { ritorni [CCDirector getAvailableKiloBytes] / 1024.0; } [...] - (vuoto) showFPS { strutture ++; l'accumDt + = dt; se (accumDt> CC_DIRECTOR_FPS_INTERVAL) { frameRate = frames/accumDt; strutture = 0; accumDt = 0; //l'unico cambiamento in showFPS è questa linea: Il NSString *str = [[NSString alloc] initWithFormat:@" il %.1f il %.1f", frameRate, [CCDirector getAvailableMegaBytes]]; [Il FPSLabel setString:str]; [rilascio di str]; } }
Sollevamento di coscienza a Scene perdenti
Inoltre molto, fortemente e con rinforzo massimo (senza tirare fuori un'arma) raccomando a progettisti cocos2d di controllare frequentemente metodi dealloc della Sua scena. Preferibilmente aggiunga un punto di arresto di una esecuzione là, o come minimo aggiunga la linea di taglio e trasporto dei tronchi: CCLOG (”dealloc: il %”, stesso). Se Lei vuole un metodo più visibile ma meno importuno Lei poteva fare qualcosa come luccichio dello schermo o interpretazione di un suono ogni volta che l'ultima scena è deallocated, in modo che Lei diventi così solito di questo che quando Lei non lo sta vedendo o sentendo più questo immediatamente alza la Sua attenzione. 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.
Se in qualsiasi momento durante lo sviluppo del Suo progetto il metodo dealloc di una scena non è chiamato quando Lei cambia scene, Lei sta perdendo la memoria. Fuoriuscita della scena intera è una perdita di memoria del genere più cattivo. Lei vuole prendere questo presto mentre Lei può ancora ripercorrere i Suoi passi che potrebbero aver causato il problema. Appena Lei arriva a utilizzazione di centinaia di beni e migliaia di linee di codice e poi si rende conto che la scena non è deallocated, Lei sarà in per un giro divertente che prova a riuscire a capire dove questo sta venendo da. In quel caso, togliendo nodi infacendoli commenti finché Lei possa avvicinarsi la colpevole è probabilmente la strategia migliore, vicino a utilizzazione di Strumenti (che non ho trovato troppo utile in quei casi). 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).
Collisi con un tal problema come perché passavo l'oggetto di CCScene a subclassi in modo che loro abbiano l'accesso a metodi della scena. La subclasse ritenne la scena e fu derivata da CCNode e aggiunse al CCScene come bambino. Il problema con questo: durante ripulita della scena questo correttamente tolse tutti i nodi di bambino ma alcuni nodi di bambino ancora hanno ritenuto la scena. Per questo il loro metodo dealloc non fu mai chiamato, e a sua volta la scena fu mai deallocated. 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.









