Bonjour,
Marco en parle, c'est donc officiel, Embarcadero abandonne progressivement la gestion de la mémoire via ARC (Comptage de Référence Automatique)
je viens de traduire l'article de Marco
http://lookinside.free.fr/delphi.php...RC+sous+Delphi
Bonjour,
Marco en parle, c'est donc officiel, Embarcadero abandonne progressivement la gestion de la mémoire via ARC (Comptage de Référence Automatique)
je viens de traduire l'article de Marco
http://lookinside.free.fr/delphi.php...RC+sous+Delphi
Malheureusement toujours en cours dans la partie mobile du coup.
Le debug va encore être pas facile entre le debug sous windows et le déploiement sous Android/iOS.
c'est un peu pour cela que Embarcadero a décidé d'arrêter ARC...sur un scénario simple c'est facile à comprendre et à utiliser, mais dès que tu pars dans des scénarios complexes, il est difficile de gérer correctement les références de tes objets...et vu que sous Windows et Mobile tu n'as pas la même gestion, c'est d'autant plus difficile à tracer
Pour moi c'est pas le problème principal avec ARC, mais j'peux comprendre que ça dérange. Ce qui me gêne c'est surtout l'appel des destructeurs quand ça lui chante et non quand on le désire.
Avec l'Objective-C, c'est la principale action de ARC : analyser le code (avec clang, compilateur créé par Apple) et placer les destructeurs au bon endroit (<- d'après Wiki, il peut placer aussi les constructeurs)
Le but de ARC , c'était pour Apple, de faire venir en natif iOS les développeurs en se rapprochant du Java/ ramasse-miettes d'Android.
Mais de base, Objective-C propose le compteur de références, qui n'a rien avoir avec ARC About Memory Management (<- lien en anglais, documentation Apple)
ARC a juste apporté des mots clefs pour marquer ses pointeurs en faible/ fort/ dangereux pour justement aider l'analyseur de code.
c'est le principe du "coder une fois, déployez partout" : à un moment on est obligés de faire confiance à l'outil qu'on utilise pour développer
pour être serein, utilise FreeAndNil() systématiquement quand tu n'as pas besoin des classes que tu as créées, ça "règle" la question de ARC.
non le problème avec ARC c'est qu'il change la façon dont on doit coder.
exemple hors ARC tu crées un objet qui possède un Owner, tu lui affectes des enfants et tu le places dans un TObjectList, tu peux décider dans le Destroy de cet objet de le déférencer de son parent, de supprimer ses enfants et de le supprimer de l'ObjetList, il te suffit de faire un Object.Free et le tour est joué....en ARC Free ne fait strictement rien, et mettre l'objet à nil n’appellera pas le destructor car il a des références un peu partout...c'est au contraire quand toutes les références à l'objet auront été supprimées qui sera finalement détruit...d'où la présence de DisposeOf qui force un peu les choses mais qui est en fait un antipattern ARC. Ou alors il faut jouer avec [weak] ou [unsafe], mais en tout état de cause, le comportement de ton code sera différent entre non-ARC et ARC; sur ce point tout le monde était d'accord pour dire que ce n'est pas gérable, il y avait ceux qui voulaient ARC partout, et ceux qui ne voulait pas d'ARC...c'est ce dernier choix qui a été retenu, notamment pour être compatible avec le code existant qui n'a pas été codé pour ARC.
ce que j'espère (je le réclame depuis longtemps) c'est qu'on puisse avoir un mot clé spécifique pour déclarer une instance locale
NB: il existe une asture pour cela qui peut s'écrire comme ceci
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 procedure TForm1.Button1Click(Sender); var SL: TStringList; autofree; begin SL := TStringList.Create; SL.LoadFromFile('exemple.text'); ShowMessage(SL.Text); // pas besoin de try/finally/free sur SL car "autofree" s'en charge end;
cela tient en quelques ligne de code
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 procedure TForm1.Button1Click(Sender); var SL: TStringList; begin SL := TStringList.Create; AutoFree(SL); SL.LoadFromFile('exemple.text'); ShowMessage(SL.Text); // pas besoin de try/finally/free sur SL car "autofree" s'en charge end;
le principe est ici de créer une Interface qui contient l'objet à libérer, comme celle-ci est retournée par la fonction AutoFree, Delphi se chargera de libérer cette interface en fin de procédure, et son Destroy libérant l'objet, celui-ci sera également détruit.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 type TAutoFree = class(TInterfacedObject) private FObj: TObject; public constructor Create(AObj: TObject); destructor Destroy; override; end; constructor TAutoFree.Create(AObj: TObject); begin inherited Create; FObj := AObj; end; destructor TAutoFree.Destroy; begin FObj.Free; inherited; end; function AutoFree(Obj: TObject): IInterface; begin Result := TAutoFree.create(Obj); end;
à noter que cela repose sur une fonctionnalité non documentée, à savoir l'interface est libérée en fin de procédure et non immédiatement après l'appel à AutoFree comme on pourrait s'y attendre
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 procedure TForm1.Button1Click(Sender); var SL: TStringList; begin SL := TStringList.Create; {temp := }AutoFree(SL); { try } SL.LoadFromFile('exemple.text'); ShowMessage(SL.Text); // pas besoin de try/finally/free sur SL car "autofree" s'en charge { finally temp := nil; // ce qui appelle TAutoFree.Destroy qui va détruire SL end; } end;
Et paf, je tombe dans le panneau. Je lis le code, et là dans ma tête : "Attention Paul, ton objet AutoFree va être libéré direct vu que tu ne le mets pas le result dans une var IInterface" ... puis je lis ce que tu écris après
Intéressant comme technique.
Mais je crois qu'une autre méthode sera possible en 10.3 avec les smart pointers devenus possibles avec l'arrivée de constructeur/destructeurs sur record, d'après ce message de pprem
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager