2009-11-06 169 views
0

當我在ViewControllers之間移動時,我的應用程序崩潰。這是導致crashViewController顯示confirmViewController的序列。當我按下confirmViewController中的後退按鈕返回到salesViewController時,應用程序崩潰。iphoneSDK:UINavigationController後退按鈕導致應用程序崩潰

我不知道爲什麼。這是兩個控制器的代碼。

在此先感謝。

#import "salesViewController.h" 


@implementation salesViewController 

@synthesize txtCardNumber; 
@synthesize txtExpires; 
@synthesize txtGrandTotal; 
@synthesize txtZip; 
@synthesize txtEmail; 
@synthesize txtCCV2; 
@synthesize txtInvoice; 

//@synthesize button; 

@synthesize strSaleType; 



- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 
    if(self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { 



    } 
    return self; 
} 

-(IBAction)btnTipCalculator:(id)sender 
{ 
    NSLog(@"I was pressed"); 

    tipCalcViewController *tipVC = [[tipCalcViewController alloc] initWithNibName:@"tipCalcView" bundle:nil]; 
    tipVC.delegate = self; 

    tipVC.passedTotal = txtGrandTotal.text; 

    [self presentModalViewController:tipVC animated:YES]; 

    [tipVC release];  

} 


-(IBAction)btnDateSelector:(id)sender 
{ 
    NSLog(@"I was pressed"); 

    DatePickerViewController *datePickerViewController = [[DatePickerViewController alloc] initWithNibName:@"datePickerView" bundle:nil]; 
    datePickerViewController.delegate = self; 

    [self presentModalViewController:datePickerViewController animated:YES]; 

    [datePickerViewController release]; 

} 

-(void)datePickerViewController:(DatePickerViewController *)controller didChooseDate:(NSString *)chosenDate{ 


    NSLog(@"Chosen Date as String: %@", chosenDate); 

    txtExpires.text = chosenDate; 


    //do processing here... for example let's set the text of the button to the chosen date 
    //[button setTitle: chosenDate forState: UIControlStateNormal]; 

    [self dismissModalViewControllerAnimated:YES]; 
} 

//callback for modal tipCalculator 
-(void)tipCalcViewController:(tipCalcViewController *)controller didChooseTip:(NSString *)chosenTip 
{ 
    NSString *strNewTotal = chosenTip; 

    //close tip calculator 
    [self dismissModalViewControllerAnimated:YES]; 

    //update GUI 
    txtGrandTotal.text = strNewTotal; 


} 


-(void)btnSubmitClicked 
{ 
    NSURL *url = [NSURL URLWithString:@"https://www.eProcessingNetwork.Com/cgi-bin/tdbe/transact.pl"]; 
    //NSURL *url = [NSURL URLWithString:@"https://www.eprocessingnetwork.com/Reflect/Post.pl"]; 
    ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] 
            initWithURL:url] autorelease]; 

    //get settings 
    //NSUserDefaults *options = [NSUserDefaults standardUserDefaults]; 
    //NSString *acctNumber = [options stringForKey:@"accountNumber"]; 
    //NSString *restrictKey = [options stringForKey:@"restrictKey"]; 

    //uncomment for actual 
    //[request setPostValue:acctNumber forKey:@"ePNAccount"]; 
    //[request setPostValue:restrictKey forKey:@"RestrictKey"]; 


    if([strSaleType compare:@"Test"] == NSOrderedSame) 
    { 
     //FOR TESTING ONLY: UNCOMMENT ABOVE FOR ACTUAL ACCOUNT 
     [request setPostValue:@"080880" forKey:@"ePNAccount"]; 
     [request setPostValue:@"yFqqXJh9Pqnugfr" forKey:@"RestrictKey"]; 

    } 


    //FOR TESTING ONLY: UNCOMMENT ABOVE FOR ACTUAL ACCOUNT 
    [request setPostValue:@"080880" forKey:@"ePNAccount"]; 
    [request setPostValue:@"yFqqXJh9Pqnugfr" forKey:@"RestrictKey"]; 


    //transaction type 
    if([strSaleType compare:@"Sale"] == NSOrderedSame) 
    { 
     [request setPostValue:@"Sale" forKey:@"TranType"]; 
    } 

    if([strSaleType compare:@"Refund"] == NSOrderedSame) 
    { 
     [request setPostValue:@"Return" forKey:@"TranType"]; 
    } 
    if([strSaleType compare:@"Test"] == NSOrderedSame) 
    { 
     [request setPostValue:@"Sale" forKey:@"TranType"]; 
    } 

    //request no HTML output 
    [request setPostValue:@"No" forKey:@"HTML"]; 

    //needed to get transID for signature capture 
    [request setPostValue:@"report" forKey:@"Inv"]; 

    //card number 
    [request setPostValue:txtCardNumber.text forKey:@"CardNo"]; 

    //parse date 
    NSString *strDateFull = txtExpires.text; 
    NSString *strMonth = [strDateFull substringWithRange: NSMakeRange(0, 2)]; 
    NSString *strYear = [strDateFull substringWithRange: NSMakeRange(3, 2)]; 

    //expire month  
    [request setPostValue:strMonth forKey:@"ExpMonth"]; 

    //expire year 
    [request setPostValue:strYear forKey:@"ExpYear"]; 

    //total, send as you would write it. no dollar sign needed 
    [request setPostValue:txtGrandTotal.text forKey:@"Total"]; 

    //address - this makes TBDE ignore requests with no address 
    [request setPostValue:@"1" forKey:@"SKIP_MISSING"]; 

    //zip 
    [request setPostValue:txtZip.text forKey:@"Zip"]; 

    //ccv2 
    [request setPostValue:@"CVV2Type" forKey:@"1"]; 
    [request setPostValue:txtCCV2.text forKey:@"123"]; 

    //email 
    [request setPostValue:txtEmail.text forKey:@"EMail"]; 

    //invoice # - optional 
    [request setPostValue:txtInvoice.text forKey:@"Invoice"]; 

    //blocking of course 
    [request start]; 


    // get confirmation 
    confirmViewController *anotherViewController = [[confirmViewController alloc] initWithNibName:@"confirmView" bundle:nil]; 

    //set properties 
    anotherViewController.strConfirmation = [request responseString]; 
    anotherViewController.strCardNumber = txtCardNumber.text; 
    anotherViewController.strExpires = txtExpires.text; 
    anotherViewController.strAmount = txtGrandTotal.text; 

    [self.navigationController pushViewController:anotherViewController animated:YES]; 


    //reset interface 
    if([anotherViewController.strApproval compare:@"""Y"] == NSOrderedSame) 
    { 
     txtCardNumber.text = @""; 
     txtExpires.text = @""; 
     txtGrandTotal.text = @""; 
     txtZip.text = @""; 
     txtCCV2.text = @""; 
     txtEmail.text = @""; 
     txtInvoice.text = @""; 
    } 

    [anotherViewController release]; 

/* 

    //display the results 
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Info" 
                message:[request responseString] 
                delegate:nil 
              cancelButtonTitle:@"OK" 
              otherButtonTitles: nil]; 
    [alert show]; 
    [alert release];  

*/ 

} 

/* 
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad. 
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { 
     // Custom initialization 
    } 
    return self; 
} 
*/ 

/* 
// Implement loadView to create a view hierarchy programmatically, without using a nib. 
- (void)loadView { 
} 
*/ 


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 
- (void)viewDidLoad { 
    [super viewDidLoad]; 

    //Needed to get events 
    [txtCardNumber setDelegate:self]; 
    [txtExpires setDelegate:self]; 
    [txtGrandTotal setDelegate:self]; 
    [txtZip setDelegate:self]; 
    [txtEmail setDelegate:self]; 
    [txtCCV2 setDelegate:self]; 
    [txtInvoice setDelegate:self]; 

    //adjust title depending on sale type 
    if([strSaleType compare:@"Sale"] == NSOrderedSame) 
    { 
     self.title = @"Sales"; 
     NSLog(@"Passed in sale type: %@", strSaleType);  

    } 
    if([strSaleType compare:@"Refund"] == NSOrderedSame) 
    { 
     self.title = @"Refunds";    
     NSLog(@"Passed here in sale type: %@", strSaleType); 

    } 
    if([strSaleType compare:@"Test"] == NSOrderedSame) 
    { 
     self.title = @"Testing";    
     NSLog(@"Passed in sale type: %@", strSaleType);  

    } 

    //add additional button 
    UIBarButtonItem *submitButton = [[UIBarButtonItem alloc] initWithTitle:@"Submit" style:UIBarButtonItemStylePlain target:self action:@selector(btnSubmitClicked)]; 
    self.navigationItem.rightBarButtonItem = submitButton; 
    [submitButton release]; 

} 

- (void)didReceiveMemoryWarning { 
    // Releases the view if it doesn't have a superview. 
    [super didReceiveMemoryWarning]; 

    // Release any cached data, images, etc that aren't in use. 
} 

- (void)viewDidUnload { 
    // Release any retained subviews of the main view. 
    // e.g. self.myOutlet = nil; 
} 


- (void)dealloc { 
    if(txtCardNumber != NULL) 
    { 
     [txtCardNumber release]; 
    } 

    if(txtExpires != NULL) 
    { 
     [txtExpires release]; 
    } 

    if(txtGrandTotal != NULL) 
    { 
     [txtGrandTotal release]; 
    } 

    if(txtZip != NULL) 
    { 
     [txtZip release]; 
    } 

    if(txtEmail != NULL) 
    { 
     [txtEmail release]; 
    } 

    if(txtCCV2 != NULL) 
    { 
     [txtCCV2 release]; 
    } 

    if(txtInvoice != NULL) 
    { 
     [txtInvoice release]; 
    } 

    if(strSaleType != NULL) 
    { 
     [strSaleType release]; 
    } 


    [super dealloc];  
} 


@end 


#import "confirmViewController.h" 


@implementation confirmViewController 

@synthesize lblStatus; 
@synthesize lblCardType; 
@synthesize lblCardNumber; 
@synthesize lblExpires; 
@synthesize lblAmount; 
@synthesize lblApproval; 

@synthesize strConfirmation; 
@synthesize strCardNumber; 
@synthesize strExpires; 
@synthesize strAmount; 
@synthesize strApproval; 


-(void)btnSignatureClicked 
{ 
    sigCaptureViewController *anotherViewController = [[sigCaptureViewController alloc] initWithNibName:@"sigCaptureView" bundle:nil]; 
    [self.navigationController pushViewController:anotherViewController animated:YES]; 
    [anotherViewController release]; 

} 

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 
- (void)viewDidLoad { 
    [super viewDidLoad]; 

    //prepare confirmation, all that is needed is the first string  
    NSArray *strings = [strConfirmation componentsSeparatedByString: @","]; 
    NSString *strPreParsed = [strings objectAtIndex:0]; 

    //break out yes/no so we can set status 
    //NSString *strYesNO = [strPreParsed substringToIndex:2]; 
    NSString *strYesOrNo = [strPreParsed substringWithRange: NSMakeRange(1, 1)]; 

    //save approval for later 
    strApproval = strYesOrNo; 

    //debug 
    NSLog(@"strNo= %@",strYesOrNo); 
    NSLog(@"strPreParsed= %@", strPreParsed); 

    //set results 
    if([strYesOrNo compare:@"Y"] == NSOrderedSame) 
    { 
     lblStatus.text = @"Approved"; 
     lblStatus.textColor = [UIColor greenColor]; 
    } 

    if([strYesOrNo compare:@"N"] == NSOrderedSame) 
    { 
     lblStatus.text = @"Declined"; 
     lblStatus.textColor = [UIColor redColor]; 
    } 

    if([strYesOrNo compare:@"U"] == NSOrderedSame) 
    { 
     lblStatus.text = @"Try Again"; 
     lblStatus.textColor = [UIColor redColor]; 
    } 

    //set card type 
    if([lblCardNumber.text compare:@"4"] == NSOrderedSame) 
    { 
     lblCardType.text = @"Visa"; 
    } 

    if([lblCardNumber.text compare:@"5"] == NSOrderedSame) 
    { 
     lblCardType.text = @"Master"; 
    } 

    if([lblCardNumber.text compare:@"6"] == NSOrderedSame) 
    { 
     lblCardType.text = @"Discover"; 
    } 


    //set cardnumber 
    lblCardNumber.text = strCardNumber; 

    //set expires 
    lblExpires.text = strExpires; 

    //set amount 
    lblAmount.text = strAmount; 

    //set approval string 
    lblApproval.text = strPreParsed; 

    //add signature button 
    UIBarButtonItem *signatureButton = [[UIBarButtonItem alloc] initWithTitle:@"Signature" style:UIBarButtonItemStylePlain target:self action:@selector(btnSignatureClicked)]; 
    self.navigationItem.rightBarButtonItem = signatureButton; 
    [signatureButton release]; 

    //set title 
    self.title = @"Approval"; 

} 


- (void)didReceiveMemoryWarning { 
    // Releases the view if it doesn't have a superview. 
    [super didReceiveMemoryWarning]; 

    // Release any cached data, images, etc that aren't in use. 
} 

- (void)viewDidUnload { 
    // Release any retained subviews of the main view. 
    // e.g. self.myOutlet = nil; 

} 


- (void)dealloc { 

    if(lblCardType != NULL) 
    { 
     [lblCardType release]; 
    } 

    if(lblCardNumber != NULL) 
    { 
     [lblCardNumber release]; 
    } 

    if(lblExpires != NULL) 
    { 
     [lblExpires release]; 
    } 

    if(lblAmount != NULL) 
    { 
     [lblAmount release]; 
    } 

    if(lblApproval != NULL) 
    { 
     [lblApproval release]; 
    } 

    if(lblStatus != NULL) 
    { 
     [lblStatus release]; 
    } 

    if(strConfirmation != NULL) 
    { 
     [strConfirmation release]; 
    } 

    if(strCardNumber != NULL) 
    { 
     [strCardNumber release]; 
    } 

    if(strExpires != NULL) 
    { 
     [strExpires release]; 
    } 

    if(strAmount != NULL) 
    { 
     [strAmount release]; 
    } 

    if(strApproval != NULL) 
    { 
     [strApproval release]; 
    } 

    [super dealloc]; 


} 


@end 

回答

1

我想你釋放不應該被釋放的特性,比如你創建strYesOrNo這樣的:

NSString *strYesOrNo = [strPreParsed substringWithRange: NSMakeRange(1, 1)]; 

不分配的字符串。所以這個字符串屬於viewDidLoad函數,並且會被這個函數釋放。但是,創造了strYesOrNo後,將其分配給一個類屬性,像這樣:

strApproval = strYesOrNo; 

到時候你的dealloc您的ViewController嘗試釋放strApproval,但viewDidLoad中媒體鏈接發佈這個值,你會得到一個壞的訪問。您可以通過strApproval分配內存解決這個問題,如:

strApproval = [[NSString alloc] initWithString:strYesOrNo]; 

我沒有經歷所有的代碼,所以也許這也適用於其他一些性質。希望這有助於。