2011-01-04 2 views
1

У меня есть утечка в моем приложении, и я не знаю почему. Возможно, у меня все дело управления памятью не так. В моем коде я получил объект UIViewController, которые имеют Ивар TelephoneValidator * валидаторУтечка на iPad, что я не понимаю

TelephoneValidator является TelephoneValidator: NSObject

Таким образом, в моей инициализации функции объекта UIViewController (initWithFieldData) У меня есть:

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

Теперь в моем viewDidLoad я получил:

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

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

Основном если мой validatorOptions не NSString Вали dator ivar стал экземпляром PhoneValidator.

В моем dealloc:

- (void)dealloc { 

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

Я проверил несколько раз, если dealloc работает, и это. После вызова dealloc валидатор освобождается (вызывая любой метод на валидаторе после того, как [релиз проверки достоверности] получает меня исключение).

И все же в «Инструментах» сказано, что пропущен PhoneValidator. И после двойного щелчка в Инструментах строка кода, которая имеет повышенную яркость, составляет:

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

Что я делаю неправильно?

UPDATE:

Вот мой заголовок информация 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; 

}

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 

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

Я думаю, что нет ничего плохого в этих частях кода, должно быть, где-то еще. –

+0

Я тоже так думал, что здесь ничего плохого. Тем не менее, Инструменты продолжают настаивать на том, что утечка здесь. Мое приложение работает в контроллере навигации, поэтому я нажимаю свой UIViewController, и именно тогда у меня эта утечка. С чего начать поиск кода? Это единственное место, где я использую этот объект (PhoneValidator). – Ertai

+0

делает '[[PhoneValidator alloc] initWithOptions: validatorOptions]' сохранить что-нибудь? Отправьте этот код. –

ответ

1

См обе эти линии

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

и внутри initWithOptions

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

Вы allocing дважды валидатор, так что есть утечка.

+0

Спасибо, утечка ушла :) – Ertai

1

Не может быть, что инструменты указывают на validatorOptions как источник утечки? Является ли это сохраненным имуществом, выпущенным на dealloc или нет? Я не могу сказать точно, код, который вы опубликовали, недостаточно, чтобы прийти к выводу.

Кроме того, как будет указано в файле willcodejavaforfood, вы всегда должны позвонить [super dealloc]; в конце вашего метода dealloc. После этого код не должен появляться.

Редактировать:

Я вернулся. Но Бруно Домингус уже понял это, вы выделяете дважды, и в этом случае первая течет.Вы должны изменить свой -initWithOptions: код:

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

    return self; 
} 
+0

Я переместил [super dealloc] в кучу всего. Возможно, я не могу использовать Инструменты правильно. То, что я делаю, это: 1. добраться до точки в моем приложении, где происходит утечка. 2. На вкладке «Вложенные блоки» у меня есть PhoneValidator (так что это не validatorOptions), тогда какой-то адрес, а затем количество пропущенных байтов, тогда мое имя приложения (как ответственная библиотека), а затем ответственный фрейм - это имя моего UIViewController. Теперь я дважды нажимаю на текст PhoneValidator, и он вводит меня в код, который я опубликовал. Я мог бы предоставить больше кода, но что именно вы имеете в виду по statint, что этого недостаточно? – Ertai

+0

Вы используете инструменты в порядке. Я имел в виду, что недостаточно заключить, что 'validatorOptions' протекает. Вы проверили, действительно ли это объект, который протекает? Как вы объявили и где вы отпустите 'validatorOptions'? – Altealice

+0

validatorOptions - еще один ivar, и он установлен в initilizier: validatorOptions \t = [fieldData objectForKey: @ "fieldValidator"] сначала у меня нет освобождения на validatorOptions, но после вашего комментария я обновил мой dealloc и теперь есть \t [ validatorOptions release]; Но утечка возникает, когда я создаю UIViewController (после viewDidLoad), а не когда я возвращаю его обратно. Я немного смущен, почему возникает утечка, когда вы только что создали объект? – Ertai

Смежные вопросы