Bernd
Bernd

Reputation: 11523

UIGestureRecognizer causing "EXC_BAD_ACCESS" error

Using the GestureRecognizer attached to a view triggers my app to crash with EXC_BAD_ACCESS error. Here's the classes involved

BoardViewController - Displaying a board (as background) set as rootViewController in the AppDelegate. It instantiates multiple objects of the "TaskViewcontroller".

//BoardViewController.h
@interface BoardViewController : UIViewController {
    NSMutableArray* allTaskViews; //for storing taskViews to avoid having them autoreleased
}

 

//BoardViewController.m - Rootviewcontroller, instantiating TaskViews    
- (void)viewDidLoad
{
    [super viewDidLoad];
    TaskViewController* taskA = [[TaskViewController alloc]init];
    [allTaskViews addObject:taskA];
    [[self view]addSubview:[taskA view]];
}

TaskViewController - An indivual box displayed on the board. It should be draggable. Therefore I attached UIPanGestureRecoginzer to its view

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIPanGestureRecognizer* panRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePan:)];
    [[self view] addGestureRecognizer:panRecognizer];
}

- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
    NSLog(@"PAN!");
}

The .xib file is a simple view.

enter image description here

All programming with the gesture recognizer I'd prefer to do in code. Any idea how to fix the error causing the app crash?

Upvotes: 4

Views: 3034

Answers (2)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726987

The method handlePan is on your view controller, not on your view. You should set the target to self:

UIPanGestureRecognizer* panRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePan:)];

EDIT (in response to the edit of the question) As omz has correctly noted, your TaskViewController gets released upon BoardViewController's viewDidLoad: exit. There are two ways of dealing with it:

  • Fold the handlePan method into the parent view controller, along with the code of viewDidLoad:, or
  • Make an instance variable for TaskViewController *taskA, rather than making it a local variable.

Upvotes: 8

Feel Physics
Feel Physics

Reputation: 2783

This is my way to use Gesture Recognizer. I think this way is easy and with low risk.

At first, you drag and drop Gesture Recognizer into the view.

ss

Then, you wire the Gesture Recognizer icon to code.

ss

Finally, you write code for this IBAction like below:

- (IBAction)handlePan:(id)sender {
    NSLog(@"PAN!");
}

You can download this project from GitHub and just run it.

https://github.com/weed/p120812_PanGesture

Upvotes: 0

Related Questions