我的应用程序漏洞了,我不知道为什么。也许我的所有记忆管理都是错误的。在我的代码中,我有UIViewController对象,它有ivar TelephoneValidator * validator
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,则验证器ivar成为TelephoneValidator实例。
在我的dealloc中:
- (void)dealloc {
if(validator != nil)
{
[validator release];
validator = nil;
}
...
[super dealloc];
}
我已经检查了几次dealloc是否有效,而且确实如此。在调用dealloc之后,验证器被释放(在[validator release]之后调用验证器上的任何方法使我异常)。
然而在仪器中,它告诉我TelephoneValidator已泄露。在双击仪器后,高位代码行是:
validator = [[TelephoneValidator alloc] initWithOptions: validatorOptions];
我做错了什么?
更新:
这是我的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 :(得分:2)
你需要在dealloc方法的末尾调用[super dealloc]。
答案 1 :(得分:1)
可能是仪器指向validatorOptions
作为泄漏的来源吗?是否是在dealloc发布的保留财产?我不能肯定地说,你发布的代码还不足以得出结论。
另外,正如willcodejavaforfood所说,你必须在你的dealloc方法结束时调用[super dealloc];
。没有代码必须在它之后。
编辑:
我回来了。但是Bruno Domingues已经把它弄好了,你要分配两次,在这种情况下,第一次泄漏。您应该将-initWithOptions:
代码更改为:
-(id) initWithOptions:(NSArray *) optionsArray;
{
if((self = [super init])){
// ... rest of code is fine
}
return self;
}
答案 2 :(得分:1)
参见这两行
validator = [[TelephoneValidator alloc] initWithOptions: validatorOptions];
和initWithOptions内部
if(self = [[TelephoneValidator alloc] init])
您正在分配两次验证器,因此存在泄漏。