{"id":6255,"date":"2011-03-29T14:49:50","date_gmt":"2011-03-29T12:49:50","guid":{"rendered":"http:\/\/www.devapp.it\/wordpress\/?p=6255"},"modified":"2011-03-29T14:49:50","modified_gmt":"2011-03-29T12:49:50","slug":"l016-gestione-della-memoria-uiviewcontroller-loadview-e-viewdidunload","status":"publish","type":"post","link":"https:\/\/www.devapp.it\/wordpress\/l016-gestione-della-memoria-uiviewcontroller-loadview-e-viewdidunload\/","title":{"rendered":"L#016 &#8211; Gestione della memoria: UIViewController, loadView e viewDidUnload"},"content":{"rendered":"<p>In un dispositivo come l&#8217;iPhone, dove la memoria \u00e8 limitata e preziosissima, un corretto uso di allocazione e deallocazione degli oggetti presenti nelle nostre interfacce grafiche (e non solo) \u00e8 una argomento molto delicato ed importante. A testimoniarlo \u00e8 la stessa classe UIViewController che, come credo abbiate potuto notare, implementa dei metodi specifici per la gestione di questo aspetto. Vediamo oggi, con questo articolo, come usare al meglio i metodi messi a disposizione per la gestione della memoria.<!--more--><\/p>\n<p>Ecco i tre metodi della classe UIViewController per la memoria:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n- (void)didReceiveMemoryWarning;\r\n- (void)loadView;\r\n- (void)viewDidUnload;\r\n<\/pre>\n<p>In questo articolo impareremo l&#8217;uso degli ultimi due.<\/p>\n<p>Premetto che personalmente non uso Interface Builder, in quanto preferisco costruire le mie interfacce grafiche da codice, a parer mio, in questo modo, tutto \u00e8 pi\u00f9 facile e gestibile, (anche se capisco che non per tutti \u00e8 cos\u00ec). In questo articolo, per\u00f2, se non siete amanti del codice sforzatevi un minimo, perch\u00e8 la semplice interfaccia grafica dell&#8217;esempio che sto per mostrarvi verr\u00e0 creata via codice.<\/p>\n<h4>&#8211; (void)loadView<\/h4>\n<p>Questo metodo viene chiamato non appena occorre caricare una vista per mostrarla all&#8217;utente. Quindi in questo metodo bisogna definire la vista del nostro UIViewController creando la view principale e aggiungendoci altri elementi grafici etc. Da notare che quando alloco e inizializzo un UIViewController non alloco in realt\u00e0 memoria per la vista, questa verr\u00e0 allocata solo quando servir\u00e0 mostrarla.<\/p>\n<p>Ecco un esempio nel quale abbiamo un UIButton e una UITableView tra le propriet\u00e0 del nostro controller:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n- (void)loadView {\r\n    \r\n    UIView *controllerView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];\r\n    \r\n    button = [[UIButton buttonWithType:UIButtonTypeInfoLight] retain];\r\n    [controllerView addSubview:button];\r\n    \r\n    tableView = [[UITableView alloc] initWithFrame:controllerView.frame style:UITableViewStylePlain];\r\n    [controllerView addSubview:tableView];\r\n    \r\n    [self setView:controllerView];\r\n    [controllerView release];\r\n}\r\n<\/pre>\n<p>Ora immaginiamo di avere un UINavigationController nel quale facciamo 1000 push di 1000 istanze di questo UIViewController&#8230; verr\u00e0 allocata tanta memoria, ma l&#8217;utente vedr\u00e0 sicuramente solo l&#8217;ultimo dei UIViewController, quindi il sistema quando riceve un avviso di &#8220;memoria esaurita&#8221; lo notificher\u00e0 a tutti gli UIViewController e quelli non visibili ( 999 istanze ) eseguiranno automaticamente il metodo <strong>-(void)viewDidUnload<\/strong> nel quale vengono rilasciati tutti gli oggetti grafici (e non solo)  che non servono al momento. Pi\u00f9 precisamente in questo metodo bisogna rilasciare gli oggetti che sono stati allocati nel metodo <strong>-(void)loadView<\/strong>, infatti, non appena il UIViewController torner\u00e0 visibile, verr\u00e0 chiamato questo metodo che ricaricher\u00e0 la grafica.<\/p>\n<p>Ecco come implementare il metodo:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n- (void)viewDidUnload {\r\n    [super viewDidUnload];\r\n    \r\n    <button class=\"btn color\"><\/button>;\r\n    button = nil;\r\n    \r\n    [tableView release];\r\n    tableView = nil;\r\n}\r\n<\/pre>\n<h4>Alcune considerazioni:<\/h4>\n<ul>\n<li>il metodo viene richiamato alla superclasse in caso abbia da rilasciare anche lei qualcosa che noi ovviamente non sappiamo<\/li>\n<li>oltre a rilasciare un oggetto dobbiamo anche <strong>eguagliarlo a &#8220;nil&#8221;<\/strong>, ma perch\u00e8?<br \/>\nMettiamo il caso qualcuno chiami un metodo che usa un nostro oggetto, se l&#8217;ggetto \u00e8 stato rilasciato, ma esiste allora avremmo un errore (crash) infatti useremmo un oggetto molto probabilmente deallocato. Se invece \u00e8 uguale a &#8220;nil&#8221; allora ogni metodo applicato a questo oggetto quindi a &#8220;nil&#8221; non avrebbe nessun effetto!\n<\/ul>\n<p><strong>Riassumendo<\/strong><\/p>\n<p>In -(void)loadView carico gli elementi che mi servono quando il controller \u00e8 visibile (non necessariamente solo la grafica, anche array o altro).<\/p>\n<p>In -(void)viewDidUnload chiamo il metodo della superclasse e rilascio ed eguaglio a &#8220;nil&#8221; <strong>tutti e soli<\/strong> gli oggetti allocati nel loadView.<\/p>\n<p>Spero vi sia utile, alla prossima \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In un dispositivo come l&#8217;iPhone, dove la memoria \u00e8 limitata e preziosissima, un corretto uso di allocazione&#8230;<\/p>\n","protected":false},"author":17,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9],"tags":[281,331,647,328,44,622,648],"class_list":["post-6255","post","type-post","status-publish","format-standard","hentry","category-guide-teoriche","tag-francesco-burelli","tag-gestione-memoria-iphone","tag-loadview","tag-release","tag-uiviewcontroller","tag-view","tag-viewdidunload"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/6255","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/users\/17"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/comments?post=6255"}],"version-history":[{"count":14,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/6255\/revisions"}],"predecessor-version":[{"id":6425,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/6255\/revisions\/6425"}],"wp:attachment":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media?parent=6255"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/categories?post=6255"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/tags?post=6255"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}