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];
}
Je pense qu'il n'y a rien de mal dans ces parties du code, doit être ailleurs. –
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
est-ce que '[[TelephoneValidator alloc] initWithOptions: validatorOptions]' conserve quelque chose? Publiez ce code. –