0

Je développe une application avec un alliage de titane. J'ai plusieurs fichiers XML. Chaque fichier xml a la même vue et chaque ID de vue et fonction est identique. cette approche est correcte ou dois-je assigner un identifiant différent et une fonction nommée différente pour tous les objets afin d'éviter les fuites de mémoire. Je veux dire que chaque proxy de xml est identique ou différent sur la mémoire?Comprendre la structure de l'alliage

home.xml

<Alloy> 
    <Window id="home"> 
<View id="Container" onTouchend="fooFunction"> </View> 
</Window> 
</Alloy> 

detail.xml

<Alloy> 
    <Window id="detail"> 
<View id="Container" onTouchend="fooFunction"> </View> 
</Window> 
</Alloy> 

other.xml

<Alloy> 
    <Window id="other"> 
<View id="Container" onTouchend="fooFunction"> </View> 
</Window> 
</Alloy> 

Et comment nettoyer l'objet de mémoire lorsque je ferme la fenêtre pour éviter les fuites de mémoire?

Édité pour l'événement de fermeture de fenêtre afin d'empêcher une fuite de mémoire;

$.detail.addEventListener("close", function() { 

     // this listerner creates when window open for paused app event 
     Ti.App.removeEventListener("app:RefreshJson", fncRefreshJson); 

     $.Container.removeAllChildren(); 
     $.detail.removeAllChildren(); 

     $.removeListener(); 
     $.destroy(); 

    // listview creates on the fly when new window opens 
    // then I am adding it into $.Container 
     listView = null; 
     $.detail = null; 

    }); 

Répondre

0

Des docs: ID doit être unique par vue, mais ne sont pas globales, si plusieurs vues peuvent avoir des composants avec le même ID.

Votre approche est correcte. Quelques notes

  • Si l'ID est omis de la composante de haut niveau dans la vue, puis alliage adoptera le nom de fichier comme identifiant. Donc, si vous avez omis id="home", alors dans home.js, vous feriez toujours référence à l'objet de la fenêtre comme ... $.home puisque c'est le nom du fichier. CamelCasing est le format commun à utiliser dans Alloy, donc View id="container" pourrait être le chemin à parcourir.
  • Des fuites de mémoire spécifiques à l'alliage peuvent se produire avec la liaison de données. Les liaisons doivent donc être properly destroyed. Autre que cela, les mêmes conseils Memory Management devraient s'appliquer. Le plus important est de ne pas utiliser d'écouteurs d'événements globaux. Si nécessaire, vous pouvez utiliser Backbone Events à la place.

Personnellement, je l'ai trouvé plus facile d'utiliser le même identifiant pour toutes mes fenêtres, comme <Window id="win"> (et $.win dans le contrôleur) donc lors du passage autour entre contrôleurs de vue, je ne dois pas regarder ou rappelez-vous ce que le nom ou le nom de fichier est pour cette fenêtre particulière.

+0

J'ai édité ma question avec mon code de contrôleur? Quelle est votre suggestion? Est-ce la bonne approche? – Kerberos

+0

Avez-vous un problème spécifique avec les fuites de mémoire? Vous voudrez peut-être poster une question sur le problème auquel vous êtes confronté. Voir aussi [gestion de la mémoire] (http://docs.appcelerator.com/platform/latest/#!/guide/Managing_Memory_and_Finding_Leaks). En ce qui concerne votre code, '$ .destroy()' n'est nécessaire que pour [alliage data binding] (http://docs.appcelerator.com/platform/latest/#!/guide/Destroying_Data_Bindings). Oui, vous devez supprimer les écouteurs d'événements globaux. J'essaierais de les éviter, et j'utiliserais plutôt des événements de backbone. –

+0

J'ouvre plus de 10 fenêtres. Les fenêtres parent ne sont pas fermantes. Suggérez-vous un algorithme pour plusieurs applications Windows? – Kerberos

0

Mon article sur ce sujet a trois ans. Mais, dans un balayage rapide, je pense que tout s'applique encore aujourd'hui. http://www.tidev.io/2014/03/27/memory-management/

Et comment nettoyer l'objet de la mémoire lorsque je ferme la fenêtre pour éviter les fuites de mémoire?

Cela dépend:

Si la fenêtre fait partie d'un groupe d'onglets, il restera en mémoire tant que l'application est en cours d'exécution.

Si c'est une fenêtre qui est ouverte dans un groupe de navigation ou dans une pile de fenêtres sur Android, cela dépend de la façon dont vous avez instancié la fenêtre.

// if you do this: 
var win = Alloy.createController('detail').getView(); 
win.open(); 

// then to clean up, after 
win.close() 
// you need to 
win = undefined; 

// which is why it's better to do this if you can 
Alloy.createController('detail').getView().open(); 

// then, inside of detail, you'd call its Window.close() 
// method which would close the window and remove the 
// last reference in memory and the object would be GC'd 

En aparté, si vous créez vraiment plusieurs fenêtres avec le code aussi similaire que vous montrer ci-dessus, vous devriez peut-être créer un widget. Vous passeriez en définissant des caractéristiques (options, noms, vues enfants, etc.) lors de l'instanciation du widget. Cette technique ne sera pas nécessairement utile avec la gestion de la mémoire ou la performance. Mais, cela aidera à éliminer le code en double.

+0

Merci beaucoup. Alors, quelle est la différence entre win = null et win = indéfini? – Kerberos

+0

J'ai édité ma question avec mon code de contrôleur? Quelle est votre suggestion? Est-ce la bonne approche? – Kerberos

+0

Il n'y a vraiment aucune différence entre 'win = null' et' win = undefined' en termes de libération d'objets natifs de la mémoire dans Titanium. Il existe des différences subtiles entre null et indéfini, mais pour ce que vous faites ici, cela n'a pas d'importance et est plus une préférence de développeur ou une habitude. Vous n'avez probablement pas besoin de '$ .removeListener();' et si vous n'utilisez pas la liaison de données Alloy avec des collections globales, vous n'avez pas besoin de '$ .destroy();' Mais, le reste de votre code de contrôleur mis à jour semble bien aussi bien que je peux dire. – skypanther