After converting to ARC I am getting "message sent to deallocated instance"

71 views Asked by At

I am creatinng an instance of a View like this...

- (IBAction)findPatientTapped:(id)sender { 

    RequestDialogViewController *findPatientViewController = [[RequestDialogViewController alloc] initWithNibName:@"RequestDialogViewController"    bundle:nil];

    findPatientViewController.delegate = self;
    findPatientViewController.autoCorrectOff = YES;
    findPatientViewController.defaultResponse = @"";
    findPatientViewController.keyboardType = @"ASCII";
    findPatientViewController.returnKeyType = @"Go";
    findPatientViewController.tag = findRequestTag;
    findPatientViewController.editSet = YES;
    findPatientViewController.titleText = @"Find Patient";
    findPatientViewController.messageText =@"Enter all or a portion of the patient's name...";
    findPatientViewController.messageText2 = @"Last Name...";
    findPatientViewController.messageText3 = @"First Name...";
    findPatientViewController.showResponse2 = YES;   
    findPatientViewController.showNavBarSaveButton = NO;
    findPatientViewController.infoTextFile = @"";
    findPatientViewController.view.frame = CGRectMake(280, 230, 480, 300);

    [self.view addSubview:findPatientViewController.view];
}

The view contains 2 UITextField fields for entry by the user. This all worked fine before running the convert to ARC tool. After the conversion the view crashes when trying to enter a value in either of the 2 fields with...

-[RequestDialogViewController respondsToSelector:]: message sent to deallocated instance

Here is the .h file of the UIViewController after running the conversion to ARC tool...

#import <UIKit/UIKit.h>
@protocol RequestDialogViewControllerDelegate;

@interface RequestDialogViewController : UIViewController <UITextFieldDelegate>{
    id<RequestDialogViewControllerDelegate> __weak delegate;
    IBOutlet UINavigationBar *navBar;
    IBOutlet UITextField *response;
    IBOutlet UITextField *response2;
    IBOutlet UILabel *message;
    IBOutlet UILabel *message2;
    IBOutlet UILabel *message3;
    IBOutlet UIButton *saveButton;
    NSTimer *selectAllTimer;

    NSString *defaultResponse;
    NSString *titleText, *infoTextFile;
    NSString *messageText, *messageText2, *messageText3;
    NSString *placeHolderText;
    NSString *keyboardType, *returnKeyType;
    BOOL editSet, showSaveButton,showNavBarSaveButton, showResponse2, autoCorrectOff;
    int tag;
}

@property (weak) id<RequestDialogViewControllerDelegate> delegate;
@property (nonatomic, strong)IBOutlet UITextField *response;
@property (nonatomic, strong) IBOutlet UITextField *response2;
@property (nonatomic, strong)IBOutlet UILabel *message;
@property (nonatomic, strong)IBOutlet UILabel *message2;
@property (nonatomic, strong) IBOutlet UILabel *message3;
@property (nonatomic, strong)IBOutlet UIButton *saveButton;
@property (nonatomic, strong)NSString *defaultResponse;
@property (nonatomic, strong)NSString *titleText, *infoTextFile;
@property (nonatomic, strong)NSString *messageText, *messageText2, *messageText3;
@property (nonatomic, strong)NSString *placeHolderText;
@property (nonatomic, strong)NSString *keyboardType, *returnKeyType;
@property (nonatomic, strong)IBOutlet UINavigationBar *navBar;
@property (readwrite)BOOL editSet, showSaveButton, showNavBarSaveButton, showResponse2, autoCorrectOff;
@property (readwrite)int tag;
@property (nonatomic, strong) NSTimer *selectAllTimer;

- (IBAction)saveButtonPressed:(id)sender;
- (void)selectAll;
- (IBAction)editingDidEnd:(id)sender;

@end


@protocol RequestDialogViewControllerDelegate <NSObject>
@optional
- (void)requestDialogViewDidDismiss:(RequestDialogViewController *)controller withResponse:(NSString*)reqResponse response2:(NSString*)reqResponse2;
@end

Here is the pertenant references in the .h file of the class creating the instance of the RequestDialog view...

#import "RequestDialogViewController.h"

@interface OrthoViewController : UIViewController <RequestDialogViewControllerDelegate>{
}
- (void)requestDialogViewDidDismiss:(RequestDialogViewController *)controller withResponse:(NSString*)reqResponse response2:(NSString*)reqResponse2;
@end

What do I need to do to make this work under ARC? I am thinking it might have something to do with how the protocol is formed.

Thanks,

John

**** Thanks to Dan I resolved this by making findPatientViewController a property of the calling class...

RequestDialogViewController *findPatientViewController;
@implementation OrthoViewController

- (IBAction)findPatientTapped:(id)sender {    
    findPatientViewController = [[RequestDialogViewController alloc] initWithNibName:@"RequestDialogViewController" bundle:nil];
    //set all the properties and add the subview
 }
@end
1

There are 1 answers

2
dan On BEST ANSWER

Your findPatientViewController has nothing retaining it, so it gets deallocated at the end of the method where you create it. Then, when something in it's view tries to call a delegate method on it you get that crash.

If findPatientTapped is a method in a view controller then you should add the findPatientViewController as a child view controller. If it's in a view, then you need to least store the findPatientViewController in a property so it doesn't get deallocated while you are still using it.

Your code didn't really work properly before ARC, you just had a memory leak.