Delegate assignment causes EXC_BAD_ACCESS - objective-c

I am trying to create a delegate for an NSTextField in my view controller, but the program crashes with EXC_BAD_ACCESS. Why does this happen? I read that I am calling a non-existent object, but I don´t know what does not exist. I am using ARC.
This is how the delegate object is created in my view controller:
#import <Cocoa/Cocoa.h>
#import "Delegate.h"
#interface ViewController : NSViewController <NSTextFieldDelegate>{
}
#end
--
#import "ViewController.h"
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSTextField* textField1 = [[NSTextField alloc] initWithFrame:NSMakeRect(200, 200, 150, 20)];
[self.view addSubview:textField1];
Delegate* delegate1 = [[Delegate alloc]init];
[textField1 setDelegate:delegate1];
}
#end
Why does my program crash?

I think the delegate1 is release, in viewDidLoad
Delegate* delegate1 = [[Delegate alloc]init];
You should create a var for handling it in ViewController.h. Then
delegate1 = [[Delegate alloc]init];

Related

cocoa nstextfielddelegate EXC_BAD_ACCESS [duplicate]

I am trying to create a delegate for an NSTextField in my view controller, but the program crashes with EXC_BAD_ACCESS. Why does this happen? I read that I am calling a non-existent object, but I don´t know what does not exist. I am using ARC.
This is how the delegate object is created in my view controller:
#import <Cocoa/Cocoa.h>
#import "Delegate.h"
#interface ViewController : NSViewController <NSTextFieldDelegate>{
}
#end
--
#import "ViewController.h"
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSTextField* textField1 = [[NSTextField alloc] initWithFrame:NSMakeRect(200, 200, 150, 20)];
[self.view addSubview:textField1];
Delegate* delegate1 = [[Delegate alloc]init];
[textField1 setDelegate:delegate1];
}
#end
Why does my program crash?
I think the delegate1 is release, in viewDidLoad
Delegate* delegate1 = [[Delegate alloc]init];
You should create a var for handling it in ViewController.h. Then
delegate1 = [[Delegate alloc]init];

UIAlertViewDelegate in separate class crashes application

I'm having difficulties with UIAlertView delegation in class other than ViewController.
Everything is fine until user clicks the OK button - then app crashes with
Thread 1: EXC_BAD_ACCESS (code=2, address 0x8)
ViewController.h:
#import <UIKit/UIKit.h>
#import "DataModel.h"
#interface ViewController : UIViewController
#end
ViewController.m:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
DataModel *dataModel = [[DataModel alloc] init];
[dataModel ShowMeAlert];
[super viewDidLoad];
}
#end
DataModel.h
#import <Foundation/Foundation.h>
#interface DataModel : NSObject <UIAlertViewDelegate>
- (void)ShowMeAlert;
#end
DataModel.m
#import "DataModel.h"
#implementation DataModel
- (void)ShowMeAlert;
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Info" message:#"View did load!" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
#pragma mark - UIAlertView protocol
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
NSLog(#"Index: %d", buttonIndex);
}
#end
If code for showing alert and it's delegation methods is in ViewController - works perfectly.
When I remove UIAlertDelegation method ...didDismissWithButtonIndex... -
works without delegation.
When I set UIAlertView delegate to nil -
works without delegation.
Any clues what's wrong?
In this method:
- (void)viewDidLoad
{
DataModel *dataModel = [[DataModel alloc] init];
[dataModel ShowMeAlert];
[super viewDidLoad];
}
you are allocating a DataModel local variable which will be deallocated by ARC at the end of the scope. Hence, when dismiss is executed, your delegate is not there anymore. The fix for this is to store your DataModel in a strong property of your view controller. This way it will not be deallocated. The you would do:
- (void)viewDidLoad
{
self.dataModel = [[DataModel alloc] init];
[self.dataModel ShowMeAlert];
[super viewDidLoad];
}

#autoreleasepool EXC_BAD_ACCESS

I have a simple UIViewControler and when i call the method [self performSelectorInBackground:#selector(load) withObject:nil]; it causes and EXC_BAD_ACCESS
Here is the UIViewControler.m and UIViewControler.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (strong, nonatomic) UITextView *myTextView;
#end
#import "ViewController.h"
#implementation ViewController
#synthesize myTextView;
- (id)init {
self = [super init];
if (self) {
myTextView = [[UITextView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[[self view] addSubview:myTextView];
[self performSelectorInBackground:#selector(load) withObject:nil];
}
return self;
}
- (void) load {
#autoreleasepool {
[myTextView setText:#"LOADING ..."];
//DO SOMETHING ....
}
}
#end
PS.:
The project uses Objective-C ARC
UIKit objects are not thread-safe: you must only access them on the main thread. The line [myTextView setText:#"LOADING ..."]; cannot be safely executed in a background thread.
This may or may not be the reason you are getting an EXC_BAD_ACCESS error but without seeing the rest of the load method I have no way of knowing what else might be wrong.

Delegate Not Working

I'm Trying to dismiss a popover and transfer data at the same time. I implemented a delegate DismissPopoverDelegate but it is failing to work. But there are no errors. If the save button is tapped it registers it and it completes the line after where it calls the delegate. But its not working...
AddEventViewController_iPad.h
#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
#import <EventKit/EventKit.h>
#import <EventKitUI/EventKitUI.h>
#import <MessageUI/MessageUI.h>
#import <MessageUI/MFMailComposeViewController.h>
#import <Foundation/Foundation.h>
#import "AboutSme.h"
#import "dateViewPopOverViewController_iPad.h"
#import "addPersonViewControllerPopover_iPad.h"
#import "PreviousEventsTableViewControllerPopover_iPad.h"
#interface AddEventViewController_iPad : UIViewController <UITableViewDelegate, UITableViewDataSource, MFMailComposeViewControllerDelegate, UITextFieldDelegate, UIAlertViewDelegate,UIPopoverControllerDelegate,UINavigationControllerDelegate,UIPopoverControllerDelegate,ABPeoplePickerNavigationControllerDelegate, ABNewPersonViewControllerDelegate, DismissPopoverDelegate> {
UIPopoverController *pop;
AddEventViewController_iPad.m
- (IBAction) selectStartDate:(id) sender {
NSLog(#"Select start date");
dateViewPopOverViewController_iPad *dateViewPopOverViewController = [[dateViewPopOverViewController_iPad alloc] init];
popover2 = [[UIPopoverController alloc] initWithContentViewController:dateViewPopOverViewController];
popover2.delegate = self;
popover2.popoverContentSize = CGSizeMake(320, 460);
CGRect rect = CGRectMake(790, 170, 175, 300);
[popover2 presentPopoverFromRect:rect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];
[dateViewPopOverViewController release];
/*
if (dateViewController == nil) {
dateViewController = [[DateViewController_iPad alloc] initWithNibName:#"DateViewController_iPad" bundle:nil];
}
[self presentModalViewController:dateViewController animated:YES];
[dateViewController retain];
*/
}
- (void) dismissWithData:(NSString *)data
{
NSLog(#"%#", data);
[pop dismissPopoverAnimated:YES];
[pop release];
}
dateViewPopOverViewController_iPad.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#protocol DismissPopoverDelegate <NSObject>
#required
- (void) dismissWithData:(NSString *)data;
#end
#interface dateViewPopOverViewController_iPad : UIViewController {
IBOutlet UIDatePicker *datePicker;
IBOutlet UISegmentedControl *segmentedBar;
IBOutlet UILabel *startLabel;
IBOutlet UILabel *endLabel;
IBOutlet UISwitch *allDaySwitch;
NSDate *startDate;
NSDate *endDate;
NSDate *now;
NSDateFormatter *dateFormatter;
id<DismissPopoverDelegate> delegate;
}
#property (retain) id delegate;
- (void) dismissWithData:(NSString *)data;
dateViewPopOverViewController_iPad.m
#implementation dateViewPopOverViewController_iPad
#synthesize startDate, endDate, datePicker, segmentedBar, startLabel, endLabel, now, allDaySwitch, delegate;
- (IBAction) save:(id)sender {
if ([self startDateIsValid] && [self endDateIsValid]) {
//[[self parentViewController] setDatesForEvent:startDate eventEndDate:endDate allDay:[allDaySwitch isOn]];
// [self dismissModalViewControllerAnimated:YES];
NSLog(#"works");
[self.delegate dismissWithData:#"Some text from popover"];
NSLog(#"works1");
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Ooops!" message:#"Please check the dates! Remember the end date must occur after the start date for the event to save." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
}
You have a circular reference when including the .h files.
dateViewPopOverViewController_iPad.h includes AddEventViewController_iPad.h and AddEventViewController_iPad.h includes dateViewPopOverViewController_iPad.h, which will cause the compiler to raise an error.
One of the aims to use protocols is to avoid this kind of circular reference. Removing the dateViewPopOverViewController_iPad.h include from your AddEventViewController_iPad.h file might fix the problem
Your call to dismissPopoverAnimated will not trigger the call to the delegate. From Apple's UIPopoverDelegate documentation:
The popover controller does not call this method in response to programmatic calls to the dismissPopoverAnimated method. If you dismiss the popover programmatically, you should perform any cleanup actions immediately after calling the dismissPopoverAnimated method.

Why does my UIWebView not Allow User Interaction?

I'm new to these forums so I apologize for my noobieness. I did as thorough a search as I could, but I couldn't find anyone else with this issue, applogise if this has been covered elsewhere.
I've created a very simple example of my problem. I'm sure I'm missing something but I can't for the life of me figure out what.
I'm creating a UIWebView and adding it to a custom view controller that inherits from UIViewController. When the app loads in the iPad simulator, the uiwebview loads the desired page, but the UIWebView is entirely unresponsive. The webview does not pan or scroll and none of the in page links can be clicked. However, if you change the orientation of the webview suddleny everything works.
Thanks in advance for your help!!
AppDelegate header
#import <UIKit/UIKit.h>
#import "EditorViewController.h"
#interface FixEditorTestAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
EditorViewController *editorView;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) EditorViewController *editorView;
#end
AppDelegate Implementation
#import "FixEditorTestAppDelegate.h"
#import "EditorViewController.h"
#implementation FixEditorTestAppDelegate
#synthesize window;
#synthesize editorView;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSLog(#"application is loading");
editorView = [[EditorViewController alloc] init];
[window addSubview:[editorView view]];
[window makeKeyAndVisible];
return YES;
}
- (void)dealloc {
[window release];
[editorView release];
[super dealloc];
}
#end
View Controller header
#import <UIKit/UIKit.h>
#interface EditorViewController : UIViewController <UIWebViewDelegate> {
UIWebView *webView;
}
#property (nonatomic, retain) UIWebView *webView;
#end
View Controller Implementation
#import "EditorViewController.h"
#implementation EditorViewController
#synthesize webView;
/*
// 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 {
NSLog(#"loadView called");
UIView *curView = [[UIView alloc] init];
webView = [[UIWebView alloc] init];
webView.frame = CGRectMake(20, 40, 728, 964);
webView.delegate = self;
webView.backgroundColor = [UIColor redColor];
[curView addSubview: webView];
self.view = curView;
[curView release];
}
//Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"viewDidLoad called");
NSURL *url = [[NSURL alloc] initWithString:#"http://www.nytimes.com"];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
[webView loadRequest:request];
[url autorelease];
[request release];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
return YES;
}
- (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 {
webView.delegate = nil;
[webView release];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
You should really be loading this from a nib, but if you're going to create it programmatically, you probably want to add this to loadView:
webView.userInteractionEnabled = YES;
webView.scalesPageToFit = YES;
I'm going to go out on a limb here, as you aren't getting much response..
There is nothing wrong with this code (out on a limb! i haven't tested it). Neither is there anything wrong with not using a .nib (but really, you would have to have a reason, right?).
Using a nib doesn't do anything magic, just pretty much what you have done here.
Your problem must be elsewhere.. can you interact with a different kind of view? A button, say? Maybe it is something to do with the window setup?
The issue is with the extra UIView you have in there. It isn't needed, and I think the touch events aren't getting enabled. I tried out the code and it didn't work like you said. Then I changed the EditorViewController to this, and it works now (all I did was to remove the extra UIView) dragging and select links now works.
- (void)loadView {
NSLog(#"loadView called");
webView = [[UIWebView alloc] init];
webView.frame = CGRectMake(20, 40, 728, 964);
webView.delegate = self;
webView.backgroundColor = [UIColor redColor];
self.view = webView;
}