Question

Semblable au problème de fuite de mémoire connu concernant la création et la destruction d'une instance de UIImagePickerController, je découvre des problèmes similaires concernant les instances de la classe UIViewController. La méthode recommandée pour utiliser UIImagePickerController consiste à créer l'instance une seule fois et à la conserver pendant toute la durée de vie de l'application, même si cela utilisera de la mémoire dont vous pourriez avoir besoin ailleurs.

La situation que je traite implique 2 instances de la classe UIViewController. Au démarrage, la première instance est créée et sa vue est ajoutée à un autre dossier "principal". Classe UIViewController faisant partie du fichier MainWindow.xib. Sur cette première instance se trouve un " info " bouton qui, une fois tapé, bascule vers une nouvelle instance de la classe UIViewController (si elle n’a pas déjà été créée). Le " principal " UIViewController gère cette commutation avec l'animation Flip habituelle. La configuration de base est décrite dans la section "Début du développement de l’iPhone: Exploration du kit de développement logiciel (SDK) de l’iPhone" " livre de Dave Mark.

Le problème qui se pose est qu’une fois le " info " Lorsque vous appuyez sur le bouton dès la première utilisation, la mémoire est allouée à la nouvelle seconde instance UIViewController et elle n'est pas libérée jusqu'à la fin de l'application. En raison du nombre d'éléments sur cette vue d'information, il utilise environ 1 Mo de mémoire une fois instancié et sa vue est ajoutée à la vue d'ensemble. Toute tentative visant à détruire et à recréer cette instance de manière cohérente entraîne une fuite de mémoire, similaire à celle qui existe si vous essayez de faire la même chose avec les instances de la classe UIImagePickerController. Je soupçonne que la cause fondamentale est la même entre les deux classes.

Le cœur de mon problème consiste à libérer autant de mémoire que possible avant de permettre à l'utilisateur de prendre une photo avec l'appareil photo. Cependant, une fois que l'utilisateur a pris une photo et qu'il voit l'image obtenue pour la première fois, il est autorisé à appuyer sur le bouton "info". bouton qui existe sur la première instance UIViewController. Une fois que vous avez appuyé sur la touche "principale" UIViewController supprime la vue UIViewController existante et la remplace par celle de l'écran d'information. L’écran d’information a un " retour " bouton pour changer les vues. Toutefois, lorsque l'utilisateur quitte l'écran d'information et choisit de prendre une autre photo avec l'appareil photo, la mémoire allouée à l'écran d'information est toujours en mémoire.

La classe UIImagePickerController utilise temporairement près de 15 à 18 Mo pour traiter l’image de 2 mégapixels avant de publier ses références internes et le paramètre "imagePickerController: didFinishPickingImage". délégué est appelé. Je reçois des alertes de mémoire insuffisante une fois que la deuxième instance UIViewController a été créée via le bouton Info, puis l'utilisateur choisit de prendre une autre photo.

Techniquement, la mémoire ne fuit pas, que vous preniez des photos à plusieurs reprises avec ou sans appuyer sur le bouton d'information dans mon cas, mais en raison d'autres problèmes concernant les processus d'arrière-plan sur l'iPhone (Safari, etc.) qui sont indépendants de votre volonté, vous DEVEZ libérer autant de mémoire que possible tout en travaillant avec des appareils tels que l'appareil photo.

Avez-vous des conseils sur la manière de créer et de détruire proprement des instances de la classe UIViewController de sorte que la mémoire ne fuit pas?

Était-ce utile?

La solution

Chargez-vous le deuxième contrôleur de vue à partir d'un NIB? Dans ce cas, vérifiez que vous libérez correctement la mémoire associée.

Voici à quoi ressemble un contrôleur de vue typique de la carte NIB dans mes projets.

SomeViewController.h

@interface SomeViewController : UIViewController {
    UILabel *someLabel;
}

@property (nonatomic, retain) IBOutlet UILabel *someLabel;

@end

SomeViewController.m

@implementation SomeViewController

@synthesize someLabel;

- (void)dealloc {
    // Release our retained IBOutlets
    self.someLabel = nil;
    [super dealloc];
}

@end

Autres conseils

Une façon de réduire votre utilisation de la mémoire serait de redimensionner l’image à la taille souhaitée (à moins bien sûr que vous souhaitiez une image 320x480). Cela a beaucoup aidé dans mon cas.

Le deuxième contrôleur de vue dont vous parlez change-t-il? Si ce n'est pas le cas, il serait préférable d'en faire un singleton et d'utiliser la même instance. Vous pouvez à tout moment modifier les valeurs utilisées par le contrôleur de vue. Cet article explique comment créer des objets singleton ( avec le code)

Un autre article ici montre l'utilisation d'une classe singleton (bien que différente de votre cas d'utilisation, il expliquera comment utiliser les singletons)

Je suggérerais également de créer un objet singleton pour UIImagePickerController.

Avez-vous des cycles dans votre chaîne de propriété? Quelque chose comme:

@interface FirstViewController: UIViewController {
  SecondViewController *secondViewController;
}
@end

@interface SecondViewController: UIViewController {
  FirstViewController *firstViewController;
}
@end

Si vous n'interrompez pas explicitement ce cycle en supprimant ces contrôleurs de vue, ils risquent de fuir.

De plus, je pense que vous êtes responsable de la libération de tous les objets de niveau supérieur chargés à partir d'un fichier nib lorsque vous n'en avez plus besoin.

Peut-être pourriez-vous enregistrer l'image avant de passer à la vue Infos. Après avoir sauvegardé l'image, relâchez l'image puis passez à la vue info. Si l'utilisateur revient en arrière, chargez l'image du dossier.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top