2 votes

La connexion NSURLConnection perturbe la mémoire de l'iPad

Nous créons une application iPad qui télécharge un ensemble de données et de documents PDF à partir d'un service Web (les données d'abord, les documents ensuite, en arrière-plan). Pour ce faire, nous utilisons SOAP via des requêtes HTTP(S). Cela fonctionne bien et, dans l'ensemble, l'application fonctionne bien. Le problème est que s'il y a trop de documents à télécharger à un moment donné, l'application se plante. En utilisant Instruments, j'ai découvert que c'est un problème de mémoire, en particulier NSRegularExpression et NSRunLoop. (J'utilise ARC)

Je pourrais améliorer mon code pour optimiser la création de NSRegularExpression. Mais je ne sais pas comment améliorer le problème du NSRunLoop.

J'ai essayé les deux, la demande HTTP asynchrone et synchrone. En utilisant l'asynchrone, j'ai dû attendre que le téléchargement se termine et comme sleep()/[NSThread sleepForTimeInterval :] ne sont pas une option, j'utilise

while ( _waitToFinish ) {
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}

En utilisant la demande de synchronisation, Instruments révèle que

[NSURLConnection sendSynchronousRequest:theRequest returningResponse:&urlResponse error:&error];

attend également avec l'aide de NSRunLoop et perturbe également la mémoire.

S'agit-il d'un bogue dans CoreFoundation ou ARC ?

Existe-t-il un autre moyen de rester inactif en attendant que les requêtes se terminent ?

Merci d'avance.

Edit :

Par "problème de mémoire", je voulais dire que l'application se plante (ou est tuée par iOS) parce qu'elle utilise trop de mémoire.

C'est ce que montrent les instruments : Instruments screenshot Le pourcentage augmente avec la durée du téléchargement de l'application.

Edit :

En allant plus loin, on s'aperçoit que c'est la NSURLConnection qui perturbe la mémoire. Il semble que j'ai oublié de configurer connection y receivedData a nil (voir Guide de programmation du système de chargement URL ). Cela a amélioré un peu l'utilisation de la mémoire.

Maintenant, il y a deux autres grandes opérations d'allocation de mémoire : enter image description here

Et voici le code que je pense correspondre à ce qu'affiche Instruments :

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [_receivedData appendData:data];
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection {    
    NSString *responseText = [[NSString alloc] initWithBytes:[_receivedData mutableBytes] length:[_receivedData length] encoding:NSUTF8StringEncoding];

    self.lastResponse = responseText;

    responseText = nil;
    connection = nil;
    _receivedData = nil;

    _lastResult = TRUE;
    _waitToFinish = FALSE;
}

Y a-t-il quelque chose que je puisse changer pour améliorer le code ?

Edit : (Titre modifié de "NSRunLoop mess up iPad memory")

Edit : J'ai créé une application de test pour prouver que c'est la NSURLConnection qui perturbe la mémoire. J'ai ensuite contacté le support aux développeurs d'Apple.

Comme je télécharge un grand nombre de PDF dans une itération avec NSURLConnection, la solution a été d'ajouter une balise @autoreleasepool { .. } dans l'itération et un autre autour de la NSRunLoop .

Merci.

1voto

rob mayoff Points 124153

Il ne s'agit pas d'un bogue dans Core Foundation ou ARC. C'est un bogue dans votre code.

N'exécutez pas la boucle d'exécution vous-même. Utilisez simplement +[NSURLConnection sendAsynchronousRequest:queue:completionHandler:] . Il appellera votre completionHandler lorsque la demande est terminée. C'est à ce moment-là que vous traitez la réponse. En attendant, il suffit de retourner hors de votre méthode et de laisser le système s'occuper de l'exécution de la boucle.

Vous dites "c'est un problème de mémoire" avec NSRegularExpression y NSRunLoop mais vous ne dites pas quel est le problème, ni quelles sont les preuves qu'Instruments vous présente. Si vous décrivez le "problème" plus en détail, nous pourrons peut-être vous aider.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X