2011-01-04 1 views
1

J'ai une fuite dans mon application et je ne sais pas pourquoi. Peut-être que j'ai toute mauvaise gestion de la mémoire. Dans mon code, j'ai UIViewController objet qui ont Ivar TelephoneValidator * validateurFuite sur iPad que je ne comprends pas

TelephoneValidator est TelephoneValidator: NSObject

Donc, dans ma fonction d'initialisation de l'objet UIViewController (initWithFieldData) J'ai:

-(id) initWithFieldData: (NSMutableDictionary*) fieldData 
{ 
... 
    validatorOptions  = [fieldData objectForKey:@"fieldValidator"]; 
... 
} 

maintenant, dans mon viewDidLoad J'ai:

- (void)viewDidLoad { 
... 
if (![validatorOptions respondsToSelector:@selector(isEqualToString:)]) { 

      validator = [[TelephoneValidator alloc] initWithOptions: validatorOptions]; 
    } 
    else { 
      validator = nil; 
    } 
... 
} 

Basicly si mes validatorOptions ne NSString vali dator ivar devient l'instance TelephoneValidator.

Dans mon dealloc:

- (void)dealloc { 

    if(validator != nil) 
    { 
      [validator release]; 
      validator = nil; 
    } 
... 
[super dealloc]; 
    } 

J'ai vérifié deux fois si fonctionne dealloc, et il est. Après l'appel de dealloc, le validateur est libéré (l'appel de n'importe quelle méthode sur validator après [release validator] me donne une exception).

Et pourtant, dans Instruments, il me dit que TelephoneValidator est une fuite. Et après avoir double-cliqué dans Instruments la ligne de code qui est highlited est:

validator = [[TelephoneValidator alloc] initWithOptions: validatorOptions]; 

Qu'est-ce que je fais mal?

MISE À JOUR:

Voici mes informations d'en-tête de UIViewController:

@interface GenericViewController : UIViewController <UITextFieldDelegate>{ 

UIImage *backgroundImage; 
NSString *step; // na ktorym kroku jestesmy 
id <GenericControllerDelegate> delegate; //delegata z ktorej bedziemy pobierali dane 
UITextField *textField; 
NSString *fieldName; //nazwa pola (potrzebujemy zeby zapisac do modelu odpowiedni tekst 
UILabel *textLabel; 
UILabel *stepsLabel; 
UILabel *prefixTextLabel; 

NSString *fieldPlaceholder; 
NSString *textLabelText; 
NSString *textLabelTextPl; //w jezyku polskim 
NSString *prefixTextLabelText; //w jezyku eng 
NSString *prefixTextLabelTextPl; //w jezyku polskim prefix 

NSString *fieldRequired; 
NSString *keyboardType; 
NSString *capitalizeType; 

UIButton *button; //forward button 
UIButton *button2; //backward button 

//to bedzie do przerobienia bo bedziemy mieli tablicje walidatorow a nie jeden walidator 
NSString *validatorType; 

//maksymalna dlugosc pola 
int maxLengthOfTextField; 

NSArray* validatorOptions; 

TelephoneValidator *validator; 

//patientModel 
PatientData *patientModel; 

}

tête de TelephoneValidator:

#import <Foundation/Foundation.h> 
#import "MAOTranslate.h" 

@interface TelephoneValidator : NSObject { 


    //opcje walidacyjne 
    NSString *phonePrefix; 
    NSString *phonePostfix; 
    int  phoneLength; 
    NSString *message; 
    NSString *messagePl; 

    UIAlertView *alertView; 
} 

-(id) initWithOptions:(NSArray *) optionsArray; 

-(void) displayMessage; 
-(BOOL) validate: (NSString *) phoneNumber; 


@end 

classe TelephoneValidator:

#import "TelephoneValidator.h" 


@implementation TelephoneValidator 
//@synthesize phoneNumber; 

-(id) initWithOptions:(NSArray *) optionsArray; 
{ 
    if(self = [[TelephoneValidator alloc] init]) 
    { 
     phonePrefix = [optionsArray objectAtIndex:0]; 
     phonePostfix = [optionsArray objectAtIndex:1]; 
     phoneLength = [[optionsArray objectAtIndex:2] intValue]; 
     message = [optionsArray objectAtIndex:3]; 
     messagePl = [optionsArray objectAtIndex:4]; 
    } 
    else { 
     self = nil; 
    } 

    return self; 


} 

//wyswietlamy wiadomosc 
-(void) displayMessage 
{ 
    NSString *displayMsg; 
    if ([[MAOTranslate getLanguage] isEqualToString:@"pl"]) { 
     displayMsg = messagePl; 
    } 
    else { 
     displayMsg = message; 
    } 

    alertView = [[UIAlertView alloc] initWithTitle:@"Alert" message:displayMsg delegate:self cancelButtonTitle:@"ok" otherButtonTitles:nil]; 
    [alertView show]; 

} 

-(BOOL) validate: (NSString *) phoneNumber 
{ 


    //dlugosc 
    if ([phoneNumber length] != phoneLength) { 
     NSLog(@"zla dlugosc"); 
     return NO; 
    } 


    NSLog(@"tutaj"); 
    //sprawdzamy prefix  
    if ([phonePrefix length]!= 0) {  
     NSLog(@"w srodku ifa"); 
     if ([phoneNumber compare:phonePrefix options:NSLiteralSearch range:NSMakeRange(0, [phonePrefix length])] != 0) { 
      NSLog(@"zly prefix"); 
      [self displayMessage]; 
      return NO; 
     } 
    } 

    //sprawdzamy postfix 
    if([phonePostfix length] != 0) 
    { 
     if ([phoneNumber compare:phonePostfix options:NSLiteralSearch range:NSMakeRange([phoneNumber length]-[phonePostfix length], [phonePostfix length])] != 0) { 
      NSLog(@"zly postfix"); 
      [self displayMessage]; 
      return NO; 
     } 
    } 


    //sprawdzamy czy string jest numeryczny 

    NSCharacterSet *alphaNums = [NSCharacterSet decimalDigitCharacterSet]; 
    NSCharacterSet *inStringSet = [NSCharacterSet characterSetWithCharactersInString:phoneNumber]; 

    if (![alphaNums isSupersetOfSet:inStringSet]) 
    { 
     NSLog(@"zly format "); 
     [self displayMessage]; 
     return NO; 
    } 

    return YES; //zwalidowany poprawnie 
} 

-(void) dealloc 
{ 

    [alertView release]; 
    alertView = nil; 
    [super dealloc]; 
} 
+0

Je pense qu'il n'y a rien de mal dans ces parties du code, doit être ailleurs. –

+0

Je pensais aussi, que rien ne va pas ici. Néanmoins, les Instruments continuent d'insister sur le fait que la fuite est ici. Mon application fonctionne dans le contrôleur de navigation, donc je pousse mon UIViewController et c'est à ce moment-là que j'ai cette fuite. Où commencer à chercher mon code? C'est le seul endroit où j'utilise cet objet (TelephoneValidator). – Ertai

+0

est-ce que '[[TelephoneValidator alloc] initWithOptions: validatorOptions]' conserve quelque chose? Publiez ce code. –

Répondre

1

Voir Ces deux lignes

validator = [[TelephoneValidator alloc] initWithOptions: validatorOptions]; 

et initWithOptions à l'intérieur

if(self = [[TelephoneValidator alloc] init]) 

Vous allocing deux fois le validateur, donc il y a une fuite.

+0

Merci, la fuite est partie :) – Ertai

2

Vous devez appeler [super dealloc] à la fin de la méthode dealloc.

+0

N'a pas aidé ... – Ertai

1

Est-il possible que les instruments pointent vers validatorOptions comme source de la fuite? S'agit-il d'une propriété conservée libérée à dealloc ou non? Je ne peux pas dire avec certitude, le code que vous avez posté n'est pas suffisant pour arriver à une conclusion.

De même, comme le dit willcodejavaforfood, vous devez toujours appeler [super dealloc]; à la fin de votre méthode dealloc. Aucun code ne doit venir après.

Éditer:

Je suis de retour. Mais Bruno Domingues a déjà eu raison, vous allouez deux fois, auquel cas, le premier fuit.Vous devez changer votre code -initWithOptions: à:

-(id) initWithOptions:(NSArray *) optionsArray; 
{ 
    if((self = [super init])){ 
    // ... rest of code is fine 
    } 

    return self; 
} 
+0

J'ai déménagé [super dealloc] à Botttom de tout. Peut-être que je ne peux pas utiliser correctement les instruments. Ce que je fais est: 1. arriver au point dans mon application où la fuite se produit. L'onglet 2.On Leaked Blocks J'ai TelephoneValidator (donc ce n'est pas validatorOptions), alors une certaine adresse puis le nombre d'octets a fui, alors mon nom d'application (comme bibliothèque responsable) alors cadre responsable est le nom de mon UIViewController. Maintenant, je double-clique sur le texte de TelephoneValidator et cela me permet d'entrer directement dans le code que j'ai posté. Je pourrais vous fournir plus de code, mais qu'entendez-vous exactement par «statint» que ce n'est pas suffisant? – Ertai

+0

Vous utilisez des instruments bien. Je voulais dire que ce n'est pas suffisant pour conclure que 'validatorOptions' fuit. Avez-vous vérifié si c'est bien l'objet qui fuit? Comment avez-vous déclaré et où libérez-vous 'validatorOptions'? – Altealice

+0

validatorOptions est un autre ivar et il est défini dans initilizier: validatorOptions \t = [fieldData objectForKey: @ "fieldValidator"] au début je n'ai pas de version sur validatorOptions mais après votre commentaire j'ai mis à jour mon dealloc et il y a maintenant \t [ version validatorOptions]; Mais la fuite se produit quand je crée UIViewController (après viewDidLoad), pas quand je le ressaisis. Je suis un peu confus, pourquoi il y a une fuite quand vous venez de créer un objet? – Ertai