2010-10-04 7 views
0

Je lis fichier PDF, puis le relâcher:iOS noyau graphique problème de gestion de la mémoire PDF

CFURLRef pdfURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), (CFStringRef)@"somepdf.pdf", NULL, NULL); 
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);  
int pagesCount = CGPDFDocumentGetNumberOfPages(pdf); 
CGPDFDocumentRelease(pdf); 

Mais la mémoire n'est pas libéré après la libération (vérifié que avec des instruments). Pourquoi? Ce qui me manque dans la gestion de la mémoire.

Merci.

EDIT

voici mon code:

- (void)loadView { 
      [super loadView]; 
      CFURLRef pdfURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), (CFStringRef)@"some.pdf", NULL, NULL); 
      pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL); 
      CFRelease(pdfURL); 
      CGPDFPageRef pdfPage = CGPDFDocumentGetPage(pdf, 1); 

      TiledPDFView * v = [[TiledPDFView alloc] initWithFrame:self.view.bounds andScale:1]; 
      [v setPage:pdfPage]; 

      [self.view addSubview:v]; 


      UIButton * but = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
      [but setTitle:@"removeView" forState:UIControlStateNormal]; 
      [but addTarget:self action:@selector(tests) forControlEvents:UIControlEventTouchDown]; 
      but.frame = CGRectMake(0, 0, 100, 40); 
      [self.view addSubview:but]; 

    } 

    -(void) tests { 
     [self.view removeFromSuperview]; 
     [self.view release]; 
     CGPDFDocumentRelease(pdf); 
    } 

pdf est variable d'instance. TiledPDFView - est extrait de l'exemple ZoomingPDFViewer. il dessine CGPDFPageRef en utilisant CATiledLayer. Après l'appel tests méthode, la vue est supprimée (devient invisible), mais la mémoire allouée avec CGPDFDocumentCreateWithURL n'est pas libérée.

+0

'CGPDFDocumentGetNumberOfPages' renvoie un' size_t', pas un 'int'. 'size_t' est non signé, alors que' int' est signé, et 'size_t' peut être plus grand (en octets, et donc à portée) que' int'. Méfiez-vous des grands documents qui ont des nombres de pages apparemment négatifs (en fait seulement très grands), ou qui ont effectivement des nombres aléatoires de pages (quand 'size_t' est plus grand que' int' et votre nombre est si grand qu'il dépasse 'int', donc une partie du nombre est supprimée). Vous devriez toujours utiliser le type correct pour les valeurs avec lesquelles vous travaillez. –

+0

Merci Peter, je vais le réparer. – negersiu

Répondre

2

Quelle mémoire n'est pas libérée? Comme vous le dites, vous avez dûment publié le document CGPDFDocument, ce qui aurait dû disparaître. Etes-vous sûr que ce n'est pas le CFURL qui reste? Vous ne vous montrez pas libérant cela, mais vous l'avez copié, donc vous êtes obligé de le faire. Voir the Memory Management Guide for Core Foundation.

Vous pouvez utiliser l'instrument ObjectAlloc pour déterminer quels objets spécifiques restent actifs. Définissez les points de début et de fin dans la ligne de temps avant que l'objet ait été créé et après qu'il ait été libéré, respectivement, puis définissez l'instrument pour afficher "Objets créés & Toujours en vie". Vous pouvez également utiliser l'instrument Leaks pour vous montrer quels objets sont encore vivants et que vous n'avez plus de pointeur. Les deux instruments présentent initialement une décomposition par classe, dans laquelle vous pouvez explorer les instances, puis les événements (allocations, rétentions, autoreleases, releases et libérations).

+0

La mémoire allouée avec CGPDFDocumentCreateWithURL n'est pas libérée (environ 3 Mo sont alloués et sont toujours utilisés). J'ai édité mon code en question – negersiu

+0

Ne devriez-vous pas mettre la propriété 'self.view' à' nil' plutôt que de relâcher la vue sur laquelle vous tenez? Aussi, avez-vous vérifié que la page (dont je suppose que la vue a été conservée) a été libérée? –