probleme dans mon application apres lancement de plusieurs application

paddevpaddev Membre
Bonjour,

Je viens de finir mon application qui marche tres bien quand je la lance toute seule.
Je teste sur ipod (128 de ram).
Si je lance d'autres appli, genre 5 ou 6 ( appli d'infos(lemonde,..) ,etc) et que je retourne sur la mienne , au bout d'un moment elle merde ( fond qui n'apparait plus).
Est ce que cela vient du fait que n'ayant que 128 mo de ram , au bout d'un moment l'ipod veuille faire de la place?
car les autres appli que j'ouvre n'ont pas ce probleme.
Avez vous deja eu ce probleme?

merci

Réponses

  • AliGatorAliGator Membre, Modérateur
    21:29 modifié #2
    Oui c'est dû à  une mauvaise gestion de la mémoire dans ton application.

    - Relis ton code et la façon dont tu gères la mémoire
    - Utilise les outils adaptés : l'analyse statique (Clang Static Analyzer -- soit via l'outil "Build & Analyze" de Xcode3 soit via le scheme adéquat dans Xcode4), Instruments pour tracker les leaks, etc.
  • paddevpaddev Membre
    21:29 modifié #3
    ok je vais regarder de plus pres.
    En fait j'utilise ARC donc deja je ne m'occupe pas des retain et release.
    Donc Je reçois en fait un ReceiveMemoryWarning.
    Pourtant mon appli ne fait que 8mo.
    J'ai fait un analyse, il n'y as aucun souci?
    D'ou peut venir le probleme?
    C'est vraiment pas evident de trouver...mais je persevère!
  • DrakenDraken Membre
    novembre 2011 modifié #4
    iPod Touch de troisième génération, je présume ? Il y a beaucoup moins de 128 Mo utilisable dans cette machine. Le système en consomme pas mal pour ces besoins propres. Il doit rester entre 16 et 20 Mo de libre pour TOUTES les applications. Ce n'est pas pour rien que le 3GS est passé à  256 Mo, et le 4G à  512 Mo !

    Ton application reçoit un ReceiveMemoryWarning quand iOS manque de place. Cela veut dire "SVP, tu ne peux pas libérer un peu de mémoire ?". Les autres applications en reçoivent aussi et doivent (théoriquement) faire de la place. Le système a du effacer ton image de fond pour gagner quelques Ko. A toi de prévoir un mécanisme de recyclage pour la recharger.

    Ceci dit, cette génération de machine est obsolète, tu sais. iOS 5 ne tournera jamais dessus. La mémoire centrale est vraiment trop faible et la puce vidéo ne supporte pas les shaders. Mine de rien, les shaders sont très importants pour les applications mobiles, en effectuant des traitements graphiques sur la puce vidéo, indépendamment du processeur central.

  • muqaddarmuqaddar Administrateur
    21:29 modifié #5
    Utilise Instruments, Allocations ou Leaks, c'est fait pour ça !
  • paddevpaddev Membre
    21:29 modifié #6
    Draken,en fait j'ai bien la derniere generation de l'ipod 8go avec ios5.
    Que veut tu dire dire par mecanisme de recyclage pour recharger l'image? En fait c'est l'image de fond de ma tableView de l'onglet "more".(j'ai crée une class tabBar).
    J'ai testé avec instrument et il indique rien, juste 2,3 petits drapeaux noirs quand je lis une vidéo mais pas de leak.
    Bref je suis un peu perdu...

    Merci a vous quand même pour les pistes!
  • AliGatorAliGator Membre, Modérateur
    21:29 modifié #7
    Si tu es sur une machine qui n'a pas bcp de RAM (ne pas confondre RAM et espace disque hein) et en plus que tu as iOS5 dessus (je suppose plus gourmand que les OS précédents ?), il ne te reste plus de toute façon bcp de mémoire pour ton appli.

    Alors après tu n'as peut-être pas de leak. Mais ça n'empêche pas que tu dois gérer la mémoire quand tu reçois un MemoryWarning (qui est envoyé quand ton appli n'a plus bcp de mémoire dispo et demande "help laisse moi un peu de place STP !"). Genre si tu reçois un memory warning qui fait qu'il va libérer l'image de fond, quand tu reviens dans ton app si l'image a été libérée tu la recharges, etc.
  • paddevpaddev Membre
    21:29 modifié #8
    je pense avoir 128 ou 256 de ram je pense.
    Mais a part un probleme de release (qui sont du coup gerer par ARC) je ne vois pas comment gerer la mémoire  vu que j'ai pas de leak surtout que mon appli fait que 8mo...
    Dans mon appli j'ai des actus appelé via un parser xml, une carte, des photos et videos.(precision: aucune des photos et videos sont dans l'appli , elles sont hebergé sur un serveur et sont leur lien sont dans un fichier xml)
    je ne comprend pas pourquoi j'ai un receivememorywarning du coup vu que je n'ai pas de leak..
  • iSofTomiSofTom Membre
    21:29 modifié #9
    Quand on reçois un memoryWarning, le système va appeler les méthodes viewDidUnload sur certains de tes controllers non "affichés", ce qui aura pour effet de supprimer leurs vues, et tu peux (c'est même conseillé) surcharger cette méthode pour toi aussi supprimer des vues que tu pourras recréer plus tard. Quand tu réafficheras ton controller, le système va se rendre compte que sa vue a été déchargée et va appeller la méthode viewDidLoad dès qu'il l'aura rechargé, ici encore tu dois surcharger cette méthode et créer tes vues. Ton problème peut venir du fait que tu crées ton imageView dans le init, mais la décharge bien dans le viewDidUnload...
  • paddevpaddev Membre
    21:29 modifié #10
    Alors je viens de faire un essai en rajoutant une webView (qui accede a un site) .
    Quand je fais instrument la j'ai bien un leak dans le fichier de mon parser TBXML..

    j'ai ceci:

    &nbsp;  0 libsystem_c.dylib calloc<br />&nbsp;  1 libdispatch.dylib dispatch_source_create$VARIANT$up<br />&nbsp;  2 CFNetwork __CFURLCache::StartWorkerThreadAndOpenPersistentStore(__CFString const*, unsigned char)<br />&nbsp;  3 CFNetwork CFURLCacheCreate<br />&nbsp;  4 CFNetwork CFURLCacheCopySharedURLCache<br />&nbsp;  5 CFNetwork StorageSession::copyCacheStorage() const<br />&nbsp;  6 CFNetwork _CFURLRequestCopySessionCache(_CFURLRequest const*)<br />&nbsp;  7 CFNetwork URLConnectionClient::URLConnectionClient(URLConnection*, _CFURLRequest const*, CFURLConnectionClient_V1*, __CFDictionary const*)<br />&nbsp;  8 CFNetwork URLConnection::initialize(_CFURLRequest const*, CFURLConnectionClient_V1*, __CFDictionary const*)<br />&nbsp;  9 CFNetwork CFURLConnectionCreateWithProperties<br />&nbsp; 10 CFNetwork CFURLConnectionSendSynchronousRequest<br />&nbsp; 11 Foundation +[NSURLConnection sendSynchronousRequest:returningResponse:error:]<br />&nbsp; 12 Foundation -[NSString initWithContentsOfURL:encoding:error:]<br />&nbsp; 13 Foundation +[NSString stringWithContentsOfURL:encoding:error:]<br />&nbsp; 14 eleazar -[TBXML initWithURL:] /Users/annefevre/Desktop/eleazar/eleazar/TBXML/TBXML.m:89<br />&nbsp; 15 eleazar +[TBXML tbxmlWithURL:] /Users/annefevre/Desktop/eleazar/eleazar/TBXML/TBXML.m:52<br />&nbsp; 16 eleazar -[eleazarAppDelegate checkForUpdate] /Users/annefevre/Desktop/eleazar/eleazar/eleazarAppDelegate.m:496<br />&nbsp; 17 eleazar -[eleazarAppDelegate application:didFinishLaunchingWithOptions:] /Users/annefevre/Desktop/eleazar/eleazar/eleazarAppDelegate.m:96<br />&nbsp; 18 UIKit -[UIApplication _callInitializationDelegatesForURL:payload:suspended:]<br />&nbsp; 19 UIKit -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:]<br />&nbsp; 20 UIKit -[UIApplication handleEvent:withNewEvent:]<br />&nbsp; 21 UIKit -[UIApplication sendEvent:]<br />&nbsp; 22 UIKit _UIApplicationHandleEvent<br />
    


    et voici les leaks dans le fichier TBXML:

    - (id)initWithURL:(NSURL*)aURL {<br />	self = [self initWithXMLString:[NSString stringWithContentsOfURL:aURL encoding:NSUTF8StringEncoding error:nil]];&nbsp; //LEAK 100%<br />	if (self != nil) {<br />	}<br />	return self;<br />}
    


    @implementation TBXML<br /><br />@synthesize rootXMLElement;<br /><br />+ (id)tbxmlWithURL:(NSURL*)aURL {<br />	return [[TBXML alloc] initWithURL:aURL];&nbsp;  //LEAK 100%<br />}<br /><br />+ (id)tbxmlWithXMLString:(NSString*)aXMLString {<br />	return [[TBXML alloc] initWithXMLString:aXMLString];<br />}<br />
    



    Et dans mon eleazardelegate, une fonction que j'appelle dans application didFinishLaunchingWithOptions pour verifier que mon fichier xml n'a pas été modifié:

    -(void)checkForUpdate{<br />&nbsp; &nbsp; NSFetchRequest *dateRequest=[[NSFetchRequest alloc]init];<br />&nbsp; &nbsp; NSEntityDescription *dateEntity = [NSEntityDescription entityForName:@&quot;Update&quot; inManagedObjectContext:managedObjectContext_];<br />&nbsp; &nbsp; [dateRequest setEntity:dateEntity];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; NSMutableArray *result=[[managedObjectContext_ executeFetchRequest:dateRequest error:nil]mutableCopy];<br />&nbsp; &nbsp; dateBase=[[NSString alloc]init];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; TBXML *tbxml=[TBXML tbxmlWithURL:[NSURL URLWithString:@&quot;http://www......&quot;]]; //LEAK 100%<br />&nbsp; &nbsp; TBXMLElement *root=tbxml.rootXMLElement;<br />&nbsp; &nbsp; dateXMl=[[NSString alloc]init];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; if(root){<br />&nbsp; &nbsp; &nbsp; &nbsp; TBXMLElement *channel = [TBXML childElementNamed:@&quot;channel&quot; parentElement:root];<br />&nbsp; &nbsp; &nbsp; &nbsp; if(channel){<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TBXMLElement *lastBuildUpdate=[TBXML childElementNamed:@&quot;lastBuildDate&quot; parentElement:channel];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(lastBuildUpdate){<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dateXMl=[TBXML textForElement:lastBuildUpdate];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; }<br />	if([result count] == 0) {<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; Update *updateBase=(Update *) [NSEntityDescription insertNewObjectForEntityForName:@&quot;Update&quot; inManagedObjectContext:managedObjectContext_];<br />&nbsp; &nbsp; &nbsp; &nbsp; [updateBase setLastBuildDate:dateXMl];<br />&nbsp; &nbsp; &nbsp; &nbsp; [managedObjectContext_ save:nil];<br />&nbsp; &nbsp; &nbsp; &nbsp; [self loadXML];<br />	}<br />&nbsp; &nbsp; else{<br />&nbsp; &nbsp; &nbsp; &nbsp; Update *resultBase=(Update *)[result objectAtIndex:0];<br />&nbsp; &nbsp; &nbsp; &nbsp; dateBase=[resultBase LastBuildDate];<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; if([dateBase isEqualToString:dateXMl]){<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; else{<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for(Update*newDate in result){<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [newDate setLastBuildDate:dateXMl];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [self deleteEntity:@&quot;News&quot;];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [self loadXML];<br />&nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; <br />}<br />
    


    Voila ca m'avance pas plus!
    si quelqu'un voit le souci
  • paddevpaddev Membre
    21:29 modifié #11
    je vais regarder pour le viewDidUnload, mais vu que ARC s'occupe des release je met quoi dans le viewDidunload?
    je met genre imageview=nil?
    autre precision je fais tout en code je ne me sert pas de interface builder.
  • paddevpaddev Membre
    21:29 modifié #12
    d'ailleur j'ai un question concernant le dealloc et viewdidunload.

    Sachant que je travaille avec ARC je ne fais pas de release d'objet.
    Par contre est ce que je dois mettre tous mes objets a nil dans l dealloc et viewdid unload, genre:
    je crée un label et une vue dans le viewdidload:

    UIView *vue=[UIView alloc] initWith...
    UIlabel*label=[UIlabel alloc]..
    [vue addSubview:label];

    dealloc{
    vue=nil;
    label=nil;
    }

    viewDidUnload{
    vue=nil;
    label=nil;
    }

    j'ai lu qu'il fallait mettre les objets a nil que si ils ont été fait avec interfaceBuilder mais je ne travaille quand code.
    Merci pour votre explication car cela pourra vraiment m'aider
Connectez-vous ou Inscrivez-vous pour répondre.