7
votes

Comment libérer un objet dans A pour la boucle?

Je suis nouveau à Cocoa / Objective-C et je suis strugeuse avec les versions de mes objets. J'ai le code suivant:

- (IBAction)showHungryView:(id)sender {
    GastroCategoriesView *gastroCategoriesView = [[GastroCategoriesView alloc] initWithNibName:@"GastroCategoriesView" bundle:nil];

    [gastroCategoriesView setDataManager:dataManager];

    UIView *currentView = [self view];
    UIView *window = [currentView superview];

    UIView *gastroView = [gastroCategoriesView view];

    [window addSubview:gastroView];

    CGRect pageFrame = currentView.frame;
    CGFloat pageWidth = pageFrame.size.width;
    gastroView.frame = CGRectOffset(pageFrame,pageWidth,0);

    [UIView beginAnimations:nil context:NULL];
    currentView.frame = CGRectOffset(pageFrame,-pageWidth,0);
    gastroView.frame = pageFrame;
    [UIView commitAnimations];

    //[gastroCategoriesView release];
}


0 commentaires

3 Réponses :


9
votes

Dans votre boucle, libérez chaque gc code> Après l'avoir ajouté à la liste, car vous n'en aurez plus besoin dans votre étendue de boucle:

NSMutableArray *result = [[[NSMutableArray alloc] init] autorelease];

// An alternative to the above, produces an empty autoreleased array
NSMutableArray *result = [NSMutableArray array];


6 commentaires

Merci beaucoup. Connaissez-vous également une règle pour le problème de @property?


@ N3ON: Si une propriété est déclarée Conservez ou COPY , vous devez libérer son ivar dans la méthode dealloc de votre classe.


@BoltClock: OK merci. Mais quand devrais-je utiliser copier, conserver ou assigner?


@ N3ON: La réponse de Sherm Pendley pourrait aider.


@BoltClock: Avoir un autre problème, serait formidable si vous pouviez m'aider. J'ai édité ma première publication.


@ N3ON: Voyez si le retenir dans votre classe aide.



1
votes

La raison pour laquelle vous pouvez libérer GC une fois ajoutée à la gastrocategoryList, c'est que lorsqu'un objet est ajouté à un tableau, le tableau conserve cet objet. Donc, même si vous libérez votre GC, ce sera toujours autour; retenu par la gastrocategorylist.

Lorsque vous retournez un objet nouvellement créé à partir d'une méthode, vous devez appeler AutoRelease. Cela entraînera la libération de l'objet uniquement après que l'exécution quitte la portée de la méthode d'appel, donnant ainsi la méthode appelante une chance de faire quelque chose avec la valeur retournée.

Notez que si votre méthode commence par le mot copie ou nouveau, vous devez pas AutoRelease votre objet; Vous devez le laisser pour la méthode d'appel de la publication.

Tant que la copie vs retenir vs attribue ... En règle générale, copiez des objets qui possèdent une version mutable, telle que NSARRAY, NSSET, NSDictionary et Nstring. Cela garantira que l'objet que vous avez un pointeur n'est pas mutable lorsque vous ne le souhaitez pas.

Sinon, utilisez Conserver chaque fois que vous souhaitez que votre classe soit assurée qu'un objet est toujours en mémoire. Cela s'appliquera à presque tous les objets, à l'exception des objets considérés comme des parents de votre objet, auquel cas vous utiliseriez Attribuer. (Voir la section sur la section conserver des cycles ici ).

Notez également que vous devez utiliser Attribuer des types non d'objet tels que INT.

lire la mémoire Guide de programmation de gestion un peu; C'est assez utile.


0 commentaires

3
votes

La réponse de BoltClock est sur place sur la première partie de votre question. Je vais essayer de m'attaquer au reste.

Attribuer est destiné aux types simples et non d'objet tels que INT, DOUBLE ou STRIT. Il génère un setter qui fait une vieille affectation simple, comme dans "Foo = Newfoo". Copier et conserver la volonté, comme indiquer leur nom, soit une copie de la nouvelle valeur ("FOO = [NEWFOO Copy]") ou de le conserver ("FOO = [NEWFOO retenir]"). Dans les deux cas, le setter libérera l'ancienne valeur selon laquelle.

La question est donc de savoir quand copier et quand retenir. La réponse est ... cela dépend. Comment votre classe utilise-t-elle la nouvelle valeur? Votre classe sera-t-elle une pause si un autre code modifie l'objet entrant? Dis, par exemple, vous avez une propriété Nstring * nommée imaginativement "Thestring". Autre code peut attribuer une instance NSMutableString à Thestring - c'est légal, car il s'agit d'une sous-classe Nstring. Mais cet autre code pourrait également conserver sa propre référence à l'objet de chaîne mutable et changer sa valeur - Votre code est-il prêt à faire face à cette possibilité? Sinon, il devrait faire sa propre copie, que l'autre code ne peut pas changer.

D'autre part, si votre propre code n'empêche aucune hypothèse sur la question de savoir si elle aurait pu être modifiée et fonctionne aussi bien que c'était ou non, alors vous économiseriez une mémoire en conservant l'objet entrant au lieu de faire de manière inutile copie de celui-ci.

Fondamentalement, la règle, qui n'est malheureusement pas si simple parfois, est de penser avec précaution sur la question de savoir si votre propre code a besoin de sa propre copie privée ou de traiter correctement un objet partagé dont la valeur pourrait être modifiée par un autre code.


4 commentaires

Il y a des moments où vous devez utiliser l'affiliation sur les types d'objets cependant. Ce n'est pas seulement pour les types de non-objets.


True - Conservez les cycles, les délégués et connecté Iboutlets, pour n'en nommer que quelques-uns. J'essayais de garder cela simple, mais peut avoir simplifié un peu trop beaucoup.


J'ai toujours conservé Iboutlets ... y a-t-il une raison pour laquelle ils devraient être assignés? Sont-ils retenus par quelque chose d'autre que votre propre classe de contrôleur?


Je pensais à imiter l'ancien comportement, où iboutlet Ivar serait, s'il n'y avait pas de méthode de réglage, il suffit d'être attribué. Les vieux chiens peuvent apprendre de nouvelles astuces, mais parfois nous avons du mal à oublier les anciens ...