I can't believe i'm stumbling on something so simple:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setTitle:#"Tap me" forState:UIControlStateNormal];
[button addTarget:self action:#selector(test) forControlEvents:UIControlEventTouchUpInside];
button.frame = CGRectMake(50, 50, 120, 60);
[self.view addSubview:button];
}
return self;
}
-(void)test {
NSLog(#"Test");
}
It crashes when I press the button, with an unrecognized selector sent to instance error.
Anybody know what I could be doing wrong here?
Edit - error message:
-[__NSCFString test]: unrecognized selector sent to instance 0x29ee30
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString test]: unrecognized selector sent to instance 0x29ee30'
Edit - how it's presented (ARC):
DemoViewController *demoVC = [[DemoViewController alloc] init];
[self.window addSubview:demoVC.view];
[self.window makeKeyAndVisible];
If you are using ARC, then demoVC.view will be realeasd just after the function ends, instead of just initializing like this
DemoViewController *demoVC = [[DemoViewController alloc] init];
Make a strong property around demoVC and initialize it as this
self.demoVC = [[DemoViewController alloc] init];
Your error message indicates (most likely) that your view controller is being deallocated before the button is pushed. (It shows that the message is being sent to an NSString, which is probably occupying the memory that the view controller used to be at.)
The easiest way to hunt this down is to use zombies to confirm this and identify why your object is being deallocated early.
EDIT: Based on your presentation code, you should make, for example, an instance variable to keep a reference to your view controller. You probably also want to move your button initialization code to viewDidLoad to avoid other problems in the future. (Or just hook up the button in a nib!)
when adding any UI Component with code it need to add in viewDidLoad or loadView(if you don`t add xib file) override method.
and also you need to add parameter for sender (this is recommandation)
ex ) - (void)test:(id)sender
and add target like this.... [button addTarget:self action:#selector(test:) forControlEvents:UIControlEventTouchUpInside]
You might calling "test" method for NSString somewhere in your code.
Related
I'm created Class and it's add to the current view with non arc project. After that i'm releasing it as this.
TestViewController *tView=[[TestViewController alloc] initWithNibName:#"TestViewController" bundle:nil];
tView.view.frame=CGRectMake(10, 10,tView.view.frame.size.width , tView.view.frame.size.height);
[self.view addSubview:tView.view];
[tView release];
I added button to the TestViewController and when pressed it just crash and view this message from console.
-[TestViewController performSelector:withObject:withObject:]: message sent to deallocated instance
Anyone can explain the reason for that?
When you call [tView release]; TestViewController's dealloc method will automatically get called. And Objects of this class will be released. So Probably you have released that button in dealloc. That's why your app is crashing.
This is not the right way to do it.
You should create a custom view and add that view to self.view instead of adding viewcontroller's view.
Currently, you had declared TestViewController instance as local. So, that only it is getting crash while accessing the controls which are there in the instance.
Declare TestViewController instance in class level(ivar) and then use it.
Obviously, the target of your button is tView. [tView dealloc] is called after [tView release] as its retainCount decrease to 0.
You should declare tView as a private member variable, such as _tView, and call [_tView release] in your view controller's dealloc function.
#interface **
{
TestViewController *_tView;
}
if(!_tView){
_tView=[[TestViewController alloc] initWithNibName:#"TestViewController" bundle:nil];
}
_tView.view.frame=CGRectMake(10, 10,tView.view.frame.size.width , _tView.view.frame.size.height);
[self.view addSubview:_tView.view];
In iOS 5.*, custom container view controllers is supported. (http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html )
You can write code like this:
TestViewController *tView=[[TestViewController alloc] initWithNibName:#"TestViewController" bundle:nil];
tView.view.frame=CGRectMake(10, 10,tView.view.frame.size.width , tView.view.frame.size.height);
[self.view addSubview:tView.view];
[self addChildViewController:tView];
[tView didMoveToParentViewController:self];
[tView release];
you can use below code
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self
action:#selector(aMethod:)
forControlEvents:UIControlEventTouchDown];
[button setTitle:#"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
[self.yourViewController addSubview:button];
self.viewController means you have define your viewcontroller in .h file and then use you instance of the view controller to add your button.
then you can release your viewController [ViewController Release];
I am trying to use Leaves sample code from GitHub to display pdf file when UIButton is pressed but when executing the project it is giving error
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: [LeavesCache setDataSource:]: unrecognized selector sent to instance
Added Exception breakpoint and found that problem is at this line
From LeavesView.m
pageCache = [[LeavesCache alloc] initWithPageSize:self.bounds.size];
- (void) initialize {
backgroundRendering = NO;
pageCache = [[LeavesCache alloc] initWithPageSize:self.bounds.size];
}
From LeavesCache.m
- (id) initWithPageSize:(CGSize)aPageSize
{
if (self = [super init]) {
pageSize = aPageSize;
pageCache = [[NSMutableDictionary alloc] init];
}
return self;
}
From LeavesView.m
- (void) setDataSource:(id<LeavesViewDataSource>)value {
pageCache.dataSource = value;
}
Difference is that Leaves project is using Tableviewcontroller but i m using collection view controller with the storyboard segue. In detailviewcontroller have a uibutton which displays pdf file when it is pressed. But when pressing that uibutton it is giving error.
Thanks for help.
If you don't have a dataSource for your collection view controller, then you don't need to call it at all. All a dataSource does is tell your class where to look for the data. Your error is that there is no dataSource property in LeavesCache, and you're trying to set one.
My ViewController.m creates an instance of a myUIView.
In myUIView a UIButton is created.
All seems good, except to capture the button presses I use addTarget, at the ViewController level.
Pressing the button causes a crash, saying: "unrecognized selector sent to instance 0x6c254e0..."
Is this addTarget code wrong? Would appreciate anyone's assistance.
- (void)viewDidLoad{
<UIVIew implementation etc...>
[myUIView.myButton addTarget:self action:#selector(myButtonIsPressed:) forControlEvents:UIControlEventTouchUpInside];
}
- (void)myButtonIsPressed{
NSLog(#"Pressed!");
}
Thanks.
Simply remove : after myButtonIsPressed in the line :
[myUIView.myButton addTarget:self action:#selector(myButtonIsPressed:) forControlEvents:UIControlEventTouchUpInside];
I am trying to use addTarget:Action:forControlEvents but I am receiving a runtime exception for an unrecognized selector.
This is being called from a UIView subclass in initWithFrame.
Below is my code:
myButton = [[UIButton alloc] initWithFrame:frame];
[myButton addTarget:self action:&selector(displayList:)
forControlEvents:UIControlEventTouchUpInside];
My method:
-(void)displayList:(id)sender
When I click on the button it receive the following message:
-[MyClass displayList:]: unrecognized selector sent to instance.
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: -[MyClass displayList:]: unrecognized selector sent to instance.
MyClass is a custom control that is a UIView subclass with a UIButton and UILabel. This class is going to be placed on a ViewController of another application.
I'm not sure what I am missing. Any help would be greatly appreciated.
it should read
[myButton addTarget:self action:#selector(displayList:) forControlEvents:UIControlEventTouchUpInside];
# instead of &
[myButton addTarget:self action:&selector(displayList:) forControlEvents:UIControlEventTouchUpInside];
The syntax is #selector(displayList:)
Also, there is a change your button may not fire the event. Try creating it this way:
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; //this will return an autoreleased UIButton object, be careful.
button.frame = CGRectMake(...);
...
I have an application in which I need to be able to update what buttons may appear on the home screen and have elected to use core data to allow me to update the controlling property via XML. The core data seems to be working well and updating, and the buttons are being created, however, for some reason, the selector doesn't seem to be retained as it crashes every time I click on the button. The error log doesn't say anything - except one time when it did say "unrecognized selector sent to instance". Here is the method I use to create the buttons:
- (void)setUpNavigationButtons {
int i = 0;
for (Features *myFeature in self.features) {
CGRect buttonRect = [self makeFeatureButtonFrame:[self.features count] withMember:i];
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[aButton setFrame:buttonRect];
[aButton addTarget:self action:#selector(buttonTouched:) forControlEvents:UIControlEventTouchUpInside];
[aButton setTitle:[NSString stringWithFormat:#"%#",myFeature.name] forState:UIControlStateNormal];
[self.view addSubview:aButton];
i++;
}
}
Here is the the selector method, in the same view controller class:
- (void)buttonTouched:(id)sender{
NSLog(#"feature selected");
}
Any help is much appreciated. Please let me know if more of the code is required to ascertain anything meaningful. I don't want to ask folks to read through a mountain of it if only a molehill is required.
UPDATE: 4/27/2011
In response to the comments in the checked answer below, I am posting the code that launches the view controller. I've not had a problem with this in the past, but it's entirely possible I've picked up some bad technique in here. This is from the method application:didFinishLaunchingWithOptions method in the AppDelegate. Anyway, here is the code:
UINavigationController *navigationController = [[[UINavigationController alloc] init] autorelease];
HomeViewController *root = [[HomeViewController alloc] initWithNibName:#"HomeViewController" bundle:nil];
root.title = companyName;
root.context = [self managedObjectContext];
[navigationController pushViewController:root animated:NO];
[window addSubview:navigationController.view];
[root release];
[self.window makeKeyAndVisible];
return YES;
Disclaimer; I'm guessing here.
Perhaps your controller isn't sticking around in memory, and it needs to be retained?
[aButton addTarget:[self retain] action:#selector(buttonTouched:) forControlEvents:UIControlEventTouchUpInside];
NOTE: THE ABOVE CODE IS BAD. It merely identified the problem in the original question. See comments below for details.
That code above is probably bad if it fixes the issue, unless each button also sends [target release] when being destroyed.
Also, you should use IBAction instead of void for button actions:
- (IBAction)buttonTouched:(id)sender{
NSLog(#"feature selected");
}