Automatic Reference Counting Issue: Passing address of non-local object....

cyranocyrano Membre
Je teste l'efficacité de ARC.

J'ouvre deux streams (lecture/ecriture) que j'affecte a des variables instances iStream et oStream

<br />&nbsp; &nbsp; &nbsp; &nbsp; NSHost *host = [NSHost hostWithAddress:@&quot;ABC.DEF.GHI.JKL&quot;];<br />	<br />	[NSStream getStreamsToHost:host port:80 inputStream:&amp;iStream outputStream:&amp;oStream];<br />	<br />	[iStream retain];<br />	[oStream retain];<br />


ARC reclame des variables locales :-(

<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; NSHost *host = [NSHost hostWithAddress:@&quot;ABC.DEF.GHI.JKL&quot;];<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; NSInputStream&nbsp; *iStreamLocal;<br />&nbsp; &nbsp; &nbsp; &nbsp; NSOutputStream *oStreamLocal;<br />&nbsp; &nbsp; <br />	[NSStream getStreamsToHost:host port:80 inputStream:&amp;iStreamLocal outputStream:&amp;oStreamLocal];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; iStream = iStreamLocal;<br />&nbsp; &nbsp; &nbsp; &nbsp; oStream = oStreamLocal;<br /><br />


bien sur ce code ne fonctionne pas, iStreamLocal et oStreamLocal étant des pointeurs locaux sur "objects autoreleases" comment les affecter a mes iVars?

un petit coup de pouce

Réponses

  • 07:28 modifié #2
    Comment as-tu déclaré les iVar au départ? je ne me suis pas encore penché sur l'ARC mais il me semble qu'il faut utiliser __strong MyClass *myiVar;
    Je ne suis vraiment pas sûr de ce que j'avance hein..
    Et du coup tu peux oublier les [myIvar release];.. ce qui m'embête un peu niveau gestion mémoire.. ARC décide de tout, et je n'aime pas trop ça.
  • zoczoc Membre
    novembre 2011 modifié #3
    Non, pas besoin de __strong, il est implicite.


    Sinon, déjà , dans le premier bout de code, tu peux virer les retain parce que de toute façon tu n'as pas le droit de l'utiliser... Et pour le reste, il nous faudrait effectivement la déclaration des variables d'instance...


    Edit: Effectivement je viens de tester, même erreur... Par contre je ne vois pas pourquoi la seconde solution ne fonctionnerait pas (passer par une variable locale), MAIS en déclarant iStream et oStream comme des properties avec l'attribut retain. Ceci dit, il existe forcément une solution à  ce problème, je n'ai pas le temps de m'y mettre ce matin mais je chercherai cet après midi.




  • zoczoc Membre
    07:28 modifié #4
    Bon, d'après le guide de migration ARC, ça devrait s'écrire comme ça:

    @interface ZFAppDelegate : NSObject &lt;NSApplicationDelegate&gt;<br />{<br />&nbsp; &nbsp; NSInputStream *iStream;<br />&nbsp; &nbsp; NSOutputStream *oStream;<br />}<br /><br />@property (assign) IBOutlet NSWindow *window;<br /><br />@end<br />
    


    @implementation ZFAppDelegate<br /><br />@synthesize window = _window;<br /><br />- (void)applicationDidFinishLaunching:(NSNotification *)aNotification<br />{<br />&nbsp; &nbsp; NSHost *host = [NSHost hostWithAddress:@&quot;ABC.DEF.GHI.JKL&quot;];<br />	<br />&nbsp; &nbsp; NSInputStream __autoreleasing *localInputStream = nil;<br />&nbsp; &nbsp; NSOutputStream __autoreleasing *localOutputStream = nil;<br />&nbsp; &nbsp; <br />	[NSStream getStreamsToHost:host port:80 inputStream:&amp;localInputStream outputStream:&amp;localOutputStream];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; iStream = localInputStream;&nbsp; &nbsp; &nbsp; // iStream est __strong (implicitement), donc le compilateur va générer un retain<br />&nbsp; &nbsp; oStream = localOutputStream;&nbsp; // idem pour oStream<br />}<br /><br />@end<br />
    
  • AliGatorAliGator Membre, Modérateur
    07:28 modifié #5
    C'est ça qui me sidère dans ARC, au final c'est sensé vous faciliter la vie alors qu'en pratique c'est autant la prise de tête qu'avec la gestion mémoire "manuelle" (qui est cohérente, elle, et tout à  fait simple à  mettre en place une fois qu'on a compris les 2-3 règles de base, ça devient un pur automatisme je me pose mm plus la question moi).

    Limite je préfère encore mettre mes retain/release moi-même et donc maà®triser cela et savoir où les mettre (vu que c'est devenu un automatisme) que de me poser tout plein de questions avec ARC savoir si faut que je mette en __autoreleasing, si y'a du __strong implicite... au final ce que l'on gagne d'un côté à  ne pas avoir à  rajouter de retain/release (et qui perso me dérangeait pas voire je trouvais ça bien) on le perd en trituration de cerveau à  comprendre où le compilateur va finalement les rajouter pour nous...
  • cyranocyrano Membre
    07:28 modifié #6
    bonjour,

    @Zoc le 1er code était sans ARC, donc retain nécessaire.

    mes variables d'instance, rien de plus simple

    NSInputStream *iStream;
    NSOutputStream *oStream;

    je vais tester __autoreleasing merci (j'avais testé __strong sans succes)

    je vous tiens au courant

    @AliGator

    je vais tester sur un projet un peu "serieux" et voir si ca tient la route.



  • zoczoc Membre
    07:28 modifié #7
    dans 1322061029:

    au final ce que l'on gagne d'un côté à  ne pas avoir à  rajouter de retain/release (et qui perso me dérangeait pas voire je trouvais ça bien) on le perd en trituration de cerveau à  comprendre où le compilateur va finalement les rajouter pour nous...

    Oui mais non car en fait dans 95% des cas on n'a pas à  se triturer le cerveau puisque tout fonctionne normalement. Pour les 5% restant, comme dans le cas présent (cad la présence de double pointeur) la solution est dans le guide de migration et de toute façon aucun risque de faire une connerie puisque le compilateur te jette. Personnellement je préfère me prendre une erreur du compilateur plutôt que devoir débusquer des leaks non triviaux avec instruments...



  • AliGatorAliGator Membre, Modérateur
    07:28 modifié #8
    @zoc c'est pas faux
    J'ai encore du mal à  me faire à  ce trop plein d'assistanat quand même pour ma part mais bon qui sait...

    @cyrano : cool je suis preneur de ton retour
  • CeetixCeetix Membre
    07:28 modifié #9
    Moi je me suis tjs pas mis à  ARC.
    Vous pensez qu'au fil du temps ils obligeront les développeur à  utiliser ARC ou ce sera toujours une option ?
  • AliGatorAliGator Membre, Modérateur
    07:28 modifié #10
    Le GC a toujours été une option. Donc je pense que ARC le restera aussi.
  • CéroceCéroce Membre, Modérateur
    07:28 modifié #11
    dans 1322128051:

    Le GC a toujours été une option. Donc je pense que ARC le restera aussi.


    La situation me semble différente. Un gros inconvénient du Garbage Collector est que toutes les frameworks utilisées doivent également être compilées avec le GC. Par ailleurs, d'un point de vue conceptuel, on se rend vite compte que Cocoa n'a pas été pensée pour être utilisée avec un ramasse-miettes. Un exemple, dans la doc, à  la question "Quand défaire les bindings ?", la réponse d'Apple est "Dans la méthode -dealloc. Si vous utilisez le ramasse miettes, trouvez une autre manière" (ce qui en français se traduit par "démerdez-vous").
    Bref, ceux qui ont essayé se sont dit qu'il apportait bien plus d'inconvénients que d'avantages. Les anciens ont conservé leurs habitudes...

    Apple s'est empressée de passer les templates de Xcode à  ARC, avec l'utilisation de @autoreleasepool dans main.m, et les strong qui remplacent les retain dans les propriétés.
    Je gage qu'Apple va rapidement nous obliger à  passer à  ARC, ou plus précisément, nous obligera à  le désactiver nous-mêmes dans les options de build.
  • AliGatorAliGator Membre, Modérateur
    07:28 modifié #12
    Ah mais oui je pense aussi que tous les nouveaux templates, projets, etc auront ARC d'activés par défaut maintenant, Apple nous incitant à  y passer de plus en plus. Mais je pense que ça continuera d'être désactivable quand même. Wait & See.
  • zoczoc Membre
    07:28 modifié #13
    En tout cas, dans Xcode 4.2, on a pour l'instant le choix entre activer ou non ARC lors de la création des projets. Mais je pense également que tôt ou tard Apple ne proposera plus que des templates utilisant ARC.

  • SmySmy Membre
    07:28 modifié #14
    J'espère qu'il ne nous forcerons jamais à  utiliser ARC. Je suis un grand fan de la gestion mémoire actuelle que je trouve très logique.

    Il m'arrive même parfois de régretter l'abscence de reference counting en C pour mes devs non iPhone, ce serait si bien un free en reference counting :)
  • cyranocyrano Membre
    07:28 modifié #15
    bon je suis bufflé ;-)

    certe je partais d'un projet conséquent mais sans bug memoire connu* (a ma connaissance, d'analyse, et d'instruments). la transformation en 1clic, deux trucs a fixé (__auroreleasing et un bug decouvert ;-) et ça roule comme avant.

    bravo.

    par contre, "perdre" la gestion mémoire ça fait bizarre, genre, perte de maitrise



  • AliGatorAliGator Membre, Modérateur
    07:28 modifié #16
    dans 1322145742:

    par contre, "perdre" la gestion mémoire ça fait bizarre, genre, perte de maitrise
    Oui c'est ce qui me gène le plus également.

    Convertir un projet existant en ARC avec leur outil de conversion intégré à  Xcode4 c'est une chose, prendre de nouvelles habitudes de ne plus faire de retain/release ça risque d'être une autre paire de manches, jusqu'à  présent du peu que j'ai essayé j'ai vraiment eu l'impression de faire du code crade.
  • LeChatNoirLeChatNoir Membre, Modérateur
    :-) Moi, la crasse, ça me connait :-)

    Aller, je m'y met, je vais tenter de convertir mon projet...

    Je vous tiens au jus !
  • LeChatNoirLeChatNoir Membre, Modérateur
    Bon ben voilà , projet migré...

    2 difficultés :

    => quand on fait Edit->Refactor, il faut déplier la target et déselectionné tous les sources qu'on ne veut pas migrer. Donc j'ai décocher les frameworks qui n'étaient pas "ARC ready", aka ASIHTTPRequest et les classes d'Ali

    => les switch/case doivent avoir des accolades. Pour le switch, on a l'habitude, mais pour les case, je le faisai pas. Donc case toto : {}



    A part ça, le reste s'est déroulé sans soucis... XCode propose les modifs et on peu vérifier source par source.

    Bon, j'avoue que c'est pas transcendental niveau code... Comme j'utilise bcp les méthode de classe (style [NSArray arrayWithObjects:...] et que mon code est propre (avec les @properties + le dealloc qui va bien pour les retain), ben du coup, ça modifie effectivement mon code mais l'impact est pas énorme...



    Enfin voilà . Maintenant, reste à  penser ARC pour mes nouvelles classes :-) Ca, c'est pas encore gagné image/rolleyes.gif' class='bbc_emoticon' alt='::)' />
Connectez-vous ou Inscrivez-vous pour répondre.