2010-09-15 4 views
1

Je lis le livre de tutoriel maintenant. Quand je vois un exemple, je deviens confus. Les codes suivants montrent un moyen de chargement paresseux. Est-ce que ce tableau de motivations est publié après désaffectation de l'instance? ou occupera-t-il ce bloc de mémoire jusqu'à ce que l'application se termine.Mémoire sur le chargement paresseux

+ (NSArray *)motivations 
{ 
    static NSArray *motivations = nil; 
    if (!motivations) 
    { 
     motivations = [[NSArray alloc] initWithObjects:@"Greed",@"Revenge",@"Bloodlust",@"Nihilism",@"Insanity",nil]; 

    } 
    return motivations; 
} 

Modifier 1 Merci Georg pour un bug. Comme il s'agit d'un objet statique, le système stockera le pointeur d'objet jusqu'à ce que l'application soit terminée.

Répondre

2

Vous pouvez utiliser cette façon de cache en laisser votre point de pointeur vers un objet qui ne release ou autorelease

Je recommande d'utiliser cette approche quand vous voulez vraiment mettre en cache des données en mémoire (généralement petites ou grandes données images) qui nécessite beaucoup de temps de traitement CPU ou IO pour générer. Pour les petites données comme NSString, vous pouvez créer un nouveau tableau et revenir chaque fois que vous en avez besoin.

Modifier le commentaire: Il y a 2 choses sur imageNamed:

1/Vous ne pouvez pas contrôler ce qui est mis en mémoire cache et ce qui ne cache par imageNamed:. Vous pouvez ne pas vouloir mettre en cache une image de grande taille et ne l'utiliser qu'une seule fois, par exemple.

2/imageNamed: ne peut pas être utilisé pour obtenir une image à partir du réseau ou des dossiers du système. Il chargera uniquement à partir de votre groupe

+2

Notez que static ne concerne que le stockage des motivations du pointeur, la durée de vie des tableaux est complètement indépendante de celle-ci. –

+0

Quant à l'image, sous iPhone SDK, l'imageNamed mettra en cache l'image dans le système. Est-il nécessaire de mettre de nouveau en cache une image dans les codes? – AechoLiu

+0

il y a 2 choses: 1/vous ne pouvez pas contrôler imageNamed, ce qu'il cache et ce qu'il ne sera pas. Vous ne voulez certainement pas mettre en cache une image de 3 ou 10 Mo par exemple. 2/Vous ne pouvez pas charger toutes les images avec imageNamed, par exemple, l'image est dans un chemin spécifique dans le système ou l'image téléchargée sur Internet – vodkhang

3

L'exemple que vous montrez contient un bogue - +arrayWithObjects: renvoie une instance libérée automatiquement qui sera détruite ultérieurement. Le code était probablement destiné à être:

motivations = [[NSArray alloc] initWithObjects:@"Greed",@"Revenge",@"Bloodlust",@"Nihilism",@"Insanity",nil]; 

Avec cela, la matrice vivra jusqu'à ce que l'application se termine.

+0

ah ouais, je ne remarque même pas ce bug – vodkhang

+0

^^ "Merci, je ne remarque pas ce bug aussi – AechoLiu

+1

J'ai classé cela comme un bug sur l'analyseur statique (l'analyseur doit attraper les objets autoreleased étant assignés en variables statiques): http://llvm.org/bugs/show_bug.cgi?id=4955 –

1

Comme il s'agit d'une méthode de classe (indiquée par un + au lieu d'un - à la déclaration), aucune instance ne sera publiée. (Techniquement il y a une instance d'un objet de classe isa je pense (? Commenter si je me trompe s'il vous plait, je ne connais pas très bien le fonctionnement interne) mais ne vous inquiétez pas à ce sujet)

, qui existe en mémoire pendant toute la durée du programme, possède ce tableau. Considérez la statique comme la plus proche possible d'une variable de classe, plutôt que comme une variable d'instance. Puisque la classe existe tout le temps, le tableau existe tout le temps.

Le chargement paresseux l'empêche d'être créé jusqu'à la première fois que cette méthode de classe est appelée, donc il ne gaspille pas de mémoire tant que vous n'en avez pas besoin.

Questions connexes