2009-11-29 6 views
0

Je suis un vétéran de 15 ans de C++ et pensé que je pourrais facilement gérer les problèmes de mémoire sur l'iPhone. Mais j'ai été humilié par ce nouvel environnement à plusieurs tours. Voici mon problème. J'espère que je pose la question correctement. Fondamentalement, je conserve un tableau mutable de mon objet commun à l'appdélégate. Cela semble être l'endroit raisonnable pour conserver une collection d'objets utilisés par plusieurs vues différentes. Cependant, entre le moment où je crée et déplace la vue vers le contrôleur de navigation et le moment où la vue commence à utiliser ces valeurs, l'emplacement dans la mémoire où j'ai créé mes objets est empilé avec des valeurs différentes.collections sur appdelegate sont écrasés

J'ai passé en revue tout mon code pour m'assurer que les comptes de référence étaient exacts mais n'ont rien trouvé. Alors j'ai commenté TOUS les appels de "release" pour garantir que les objets existent toujours mais le piétinement continue.

Ma question est la suivante ... Y a-t-il quelque chose que je dois savoir quand je "pousse" une vue qui pourrait me faire piétiner la mémoire? J'ai un bouton que l'utilisateur appuie pour allouer un contrôleur de vue, puis un "pushViewController" pour le contrôleur de navigation contenant. Je vérifie sur la ligne suivante que mes objets ont été créés et je dépiste la mémoire. Malheureusement, la mémoire est écrasée lorsque l'événement du bouton se déroule sur un "PurpleEventCallback".

Est-ce que cela a du sens pour n'importe qui? Y a-t-il quelque chose qui arrive à mon point de vue qui n'est pas communément connu et qui rend ma mémoire invalide?

Répondre

1

Bienvenue sur SO! On dirait que vous faites tout correctement. Juste pour être sûr que retenir/relâcher ne cause pas de problèmes, essayez de conserver votre structure de tableau avant d'appuyer sur le contrôleur de vue. Rappelez-vous que certains constructeurs renvoient des objets avec un nombre de retenues de 1, et que d'autres retournent des objets auto-libérés avec un nombre de retenues égal à zéro. En règle générale, toutes les fonctions commençant par "new", "create" ou "alloc" renvoient des objets avec un nombre de +1. D'autres fonctions pratiques telles que [NSMutableArray arrayWithCapacity:] et [NSString stringWithFormat:] renvoient des objets qui ont été libérés automatiquement et dont le nombre de rétention est égal à zéro. Si vous gardez un pointeur sur ces objets, ils disparaîtront au hasard lorsque la boucle d'exécution nettoiera les choses.

Vous pouvez également vous intéresser au débogage à l'aide de la technique "zombies". Il est très utile lorsque vous commencez à obtenir des erreurs EXE_BAD_ACCESS au hasard. Pour plus d'informations, consultez cette page: http://www.cocoadev.com/index.pl?NSZombieEnabled

A partir de cet article: "... avec zombies activés, les messages envoyés à des objets désalloués ne se comporteront plus de manière étrange ou ne se bloqueront pas de manière difficile à comprendre, mais enregistreront un message et mourir d'une manière prévisible et débogueur-breakpoint.Ceci est l'outil à utiliser lors de la tentative de traquer les sur-versions et les versions prématurées. "

Espérons que ça aide!

+0

Pour être précis: Les méthodes qui commencent par 'alloc' ou' new' ou qui contiennent 'copy' sont les seules qui retournent des objets non auto-libérés. –

+0

+1 pour NSZombieEnabled. En tant que développeur C++ de longue date, j'avais vraiment besoin de lire Guide de programmation de gestion de mémoire pour Cocoa avec une attention particulière à la propriété. http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html –

+0

Ici, je pensais être intelligent en définissant ma taille de tableau d'origine et en créant la chaîne à la volée. Je n'avais aucune idée qu'ils étaient autoreleased. Je suis retourné et j'ai trouvé plusieurs divergences qui nécessitaient que leur nombre de refs soit dépassé. Merci! Marcus –

0

Vous n'avez peut-être pas lu le concept de pools de libérations automatiques dans Cocoa auparavant. La libération automatique d'un objet reporte la libération d'un objet à la fin du cycle d'événement en cours (ou chaque fois qu'un pool d'autorelease est drainé).

Pour vérifier si l'autoreleasing est votre problème, définissez la variable d'environnement NSEnableAutoreleasePool sur "NO". Si le problème disparaît, autorelease était votre problème.

+0

Dang il! Je pensais avoir commenté tous les chemins qui pourraient décrémenter mes objets pour voir si c'était le problème. Après avoir lu vos deux réponses je suis retourné et j'ai trouvé une "autorelease" que j'avais raté. C'était un autre de mes problèmes (en plus du précédent commentaire ci-dessus). Nous ne les avions pas en C++ donc ça va prendre un peu de temps pour s'y habituer. Merci les gars! Marcus –