Reputation: 151
I have a view controller (vc1) that uses another class in order to get UI-elements. So the view of vc1 sets as subview another view returned from a class called Layout. The view returned from the class Layout contains a UIbutton. In the Layout class I have this code:
[btn addTarget:self action:@selector(button_clicked:) forControlEvents:UIControlEventTouchUpInside];
Then in the same class (Layout) I also declared the method button_clicked:
- (void)button_clicked:(id)sender {
NSLog(@"btn clickd");
}
However, when I click the button something wrong happens. I cannot see any error message in debug area but the state of Xcode doesn't look good. The simulator loses focus and Xcode appears with a file (I guess its AppDelegate.m) with this line:
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
highlighted with green color. Also, in the code I see the message:
Thread 1: EXC_BAD_ACCESS(code=2, adress=0x9)
What could be wrong? I also am afraid that vc1 should manage the button click, so the method I think would be best to be placed inside vc1. Dont you think so?
Upvotes: 0
Views: 602
Reputation: 302
The target of your button as set in your code -
[btn addTarget:self action:@selector(button_clicked:) forControlEvents:UIControlEventTouchUpInside];
might be getting released before you click on your button.
If you want to place the method to be called on the button click inside your view controller (vc1), you can do that. Just change the target of the button from self to nil.
[btn addTarget:nil action:@selector(button_clicked:) forControlEvents:UIControlEventTouchUpInside];
and then implement the "button_clicked" method in the vc1. There might be warning in your layout class that the "button_clicked" is undeclared selector which you can ignore.
If you want to call your "button_clicked" method in the "Layout" class, you can do that. Declare a property of Layout class with strong attribute in your vc1 class. Then create an object of your layout class and instantiate the property with it.
Layout *propertyName = [[Layout alloc] init];
Now, call your function (let function name be - getViewFromLayoutClass) which returns your view as following-
[propertyName getViewFromLayoutClass]
Now when you click on your button, it should call the method in your Layout class.
Upvotes: 0
Reputation: 119031
Your description suggests that the instance of Layout
that you set as the target of the button is released before you press the button, so, when you do press it you use an invalid pointer.
Check what is retaining the instance of Layout
that you are using, and make sure it is retained (for at least the amount of time that it is the target of the button action).
Upvotes: 1