2010-11-19 3 views
9

Je suis certain que je manque une compréhension fondamentale de la gestion de la mémoire iOS et, malgré beaucoup de lecture et de recherche, je ne comprends toujours pas. J'utilise un singleton dans mon application qui contient des informations sur l'utilisateur actuellement connecté, des informations provenant de plusieurs contrôleurs de vue, etc. Il dispose de plusieurs ivars qui sont obtenus et définis dans l'application. Ils sont déclarés et possédantes dans le fichier .h comme ceci:iOS Singletons et la gestion de la mémoire

NSString *myString; 

et sont faits retenus comme ceci:

@property (non atomic, retain) NSString *myString; 

et synththesized dans la mise en œuvre.

je reçois et définir leurs valeurs dans les méthodes dans le singleton comme ceci:

myString = @"value"; 

et

methodLocalString = myString; 

Dans d'autres endroits, j'inclure le singleton - appelle CurrentUser - I l'importer:

#import "CurrentUser.h"  

En dehors du singleton je reçois et définir comme ceci:

[CurrentUser sharedCurrentUser].myString = @"Bob"; 

et

myOutsideString = [CurrentUser sharedCurrentUser].myString; 

La plupart du temps, cela fonctionne très bien, avec les valeurs d'une façon appropriée persistait à obtenir ou à la mise à l'autre. Le problème est que parfois quand je les obtiens de cette façon, je trouve qu'ils ont été libérés (écrasement de l'application), ce que NSZombieEnabled me dit heureusement.

Ce que je ne comprends pas, c'est comment ça peut arriver. Je pensais que le singleton n'était jamais sorti, et que par conséquent les propriétés conservées du singleton ne seraient jamais libérées. Je noterai que le problème semble être plus commun avec des propriétés d'objet non-réel comme des propriétés NSDate et certainement-not-object comme int et BOOL qui ne peuvent pas être conservées, mais cela arrive aussi avec des propriétés d'objet.

Qu'est-ce que j'ignore ici? Et merci pour votre patience.

+0

bonne question. en attente de la clarification. – harshalb

+1

N'utilisez pas les propriétés 'retain' avec' NSString'. Utilisez 'copy'. –

+0

Merci pour le pas sur la copie. Cela devrait être pour tous les objets qui supportent NSCopying, non? –

Répondre

14

Votre problème est:

je reçois et définir leurs valeurs dans les méthodes dans le singleton comme ceci:

myString = @"value";

Lorsque vous attribuez directement au iVar, au lieu de en utilisant la syntaxe de la propriété (self.myString = @"value"), vous contournez la méthode setter synthétisée, ce qui signifie que le retain ne se produit jamais.

Les propriétés ne sont pas magiques. Ils sont juste un peu de sucre syntaxique pour le "." accès, et la possibilité d'avoir des méthodes de getter/setter synthétisés pour vous épargner l'ennui de l'écriture de votre propre.

self.myString = @"value"; 

est un raccourci juste pour

[self setMyString:@"value"]; 

La méthode setMyString synthétisé fera quelque chose comme:

if (myString != newValue) { 
    [myString release]; 
    myString = [newValue retain]; 
} 

(en supposant l'option retain sur le @synthesize)

+0

Cela rend * parfait * le sens, merci! –

0

Don't use singletons. Votre actuelle le problème est causé par un idée fausse de gestion de la mémoire simple, mais le modèle singleton ne vous donnera plus de maux de tête à long terme.

+1

Merci pour la suggestion. J'ai lu plus d'une douzaine d'articles sur les avantages et les inconvénients, et je suis à l'aise avec mon choix. –

+2

En général, les singletons dans les applications iOS finissent par vous causer de gros maux de tête. Mais, vous pouvez les utiliser si vous faites attention. Mais, une chose que vous ne devriez jamais faire est de référencer les éléments UIKit de votre singleton. J'ai passé en revue l'utilisation par les développeurs de singletons dans de nombreux projets, et chaque fois qu'un singleton détient des références à des objets UIKit ou à d'autres objets qui référencent des objets UIKit, vous finirez par vous tirer dans le pied. L'outil de fuites de mémoire n'attrapera pas les fuites de UIKit comme ceci, et vous vous retrouverez avec un désordre de refs circulaires qui est difficile à résoudre. – MoDJ