Hey I'm trying to make a clear button for my polish calculator.. code give me this error when executing the clear button
unrecognized selector sent to instance 0x6a6e1e0'
there is a button in the interface builder linked to clearBtn
this code is in the CalculatorViewController.m
display is linked to the UILabel
and..
heres the code
- (IBAction)clearBtn
{
if (self.userIsInTheMiddleOfEnteringANumber) {
[[self display] setText:#"0"];
[self setUserIsInTheMiddleOfEnteringANumber:NO];
}
}
- (IBAction)clearAllBtn //this button works fine..
{
[[self brain] clearAll]; // the brain class has a method to set the array to nill
[[self display] setText:#"0"];
[self setUserIsInTheMiddleOfEnteringANumber:NO];
}
kind of hard to know without seeing the rest of your code, but I'd assuming it's because you don't have a method named setUserIsInTheMiddleOfEnteringANumber. Maybe double check the spelling and parameter list?
Thanks for posting the code. Generally, unrecognized selector errors are not tough, but we need to know which line of code is triggering it, which will help us understand which object is receiving the message, and what the selector is. Can you post a dump of the error messages?
Read about Objective-C selectors here.
Generally speaking, Interface Builder is a great tool for... umm, building interfaces. But you do have to be careful about connections and making sure everything is still linked up after making changes to your code or layout.
Related
I'm new to iPhone application development, but I seem to have somewhat managed so far (learning as I go).. however, I've run in to an issue I can't figure out. Here's the scenario:
I have an extension class called CoreAPI which I have my network functions inside. I have a function called "Login" inside CoreAPI which makes a request to a server, gets the 0 or 1 response and returns true or false. I had this working perfectly with Synchronous requests, but now I need to make everything asynchronous.
So, below is what I'm trying to do.. this is not working with the error along the lines of "Object of type ID has no method loginCallback"
loginViewController.m
- (void) login {
CoreAPI APIObject = [[CoreAPI alloc] init];
[APIObject login:self];
}
- (void) loginCallback {
NSLog(#"It called back.");
}
CoreAPI.m
- (void)login:(id)sender {
[sender loginCallback];
}
Thanks, and please let me know if I have missed any details needed to help me.
I'm seeing a couple problems. First, I'm guessing you don't provide visibility of the loginCallback function to CoreAPI.m. You should be able to send any message to an id type, so long as it's defined for a known type.
However, I'd recommend using a completion block in this case. Here's what that could look like:
(in CoreAPI.h)
- (void)login:(void (^)(void))completed;
(in CoreAPI.m)
- (void)login:(void (^)(void))completed {
// Login code
if (completed) completed();
}
Calling it would look like:
CoreAPI APIObject = [[CoreAPI alloc] init];
[APIObject login:^{
NSLog(#"It called back.");
}];
They have really goofy syntax, but blocks are really nice for this sort of thing. Hope this helped! Let me know if I didn't explain something clearly.
this should do the trick for you:
first, import loginViewController header inside CoreApi.m
#import "loginViewController.h"
Then, change login method to this:
- (void)login:(id)sender {
[(loginViewController*)sender loginCallback];
}
Or this:
- (void)login:(loginViewController*)sender {
[sender loginCallback];
}
Explanation: notice that your login method is receiving by parameter one object of type id . In objective C, id type means a reference to any Objective-C of unknow class. So, inside your login method, the compiler doesn't know that the sender is a instance of your loginViewController class, so it won't recognize loginViewController's methods.
To informations about this, please read: Objective-C: difference between id and void *
Notice that I only focused in remove your actual error. You should have to do more things in order to accomplish your code to run asynchronous.
In order to perform a better callback, please look for delegates or blocks (like in oltman's answer).
To run things in background, look for CDG : http://developer.apple.com/library/ios/#DOCUMENTATION/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html
just a simple problem (I hope !)
I've got a void method which add a column to a table.
Why if I call that method programmatically (ex: [self method] ) my table won't update and instead if i call it through an IBAction (pushing a button from app) it works ?
Actually i can see from the log that the method is called in both cases but update data just with IBAction.
the method:
- (IBAction)void {
NSTableColumn *column = [[NSTableColumn alloc] initWithIdentifier:#"1"];
[column setWidth:50];
[tableData addTableColumn:column];
[tableData reloadData];
[[column headerCell] setStringValue:#"aColumn"];
NSLog(#"Method called"); //The method is called in both cases
}
I can't find out what I am doing wrong.
(New to cocoa programming)
Thanks a lot !
Where did you call this programmatically? You might have called it before the view was loaded in an init method instead of something else like awakeFromNib.
I tried your code and got different results. It was called fine from code (and the table updated), but not from the button (and the log wasn't run either when attempting to call from the button).
The problem is the method name -- you shouldn't name a method void. Do you not get the error message in the console: "Could not connect the action void: to target of class AppDelegate"
The compiler won't even allow me to connect that method to the button (it looks like I can in IB, but I get that error message, and if I put the method in the .h file, it has no circle next to it that shows whether it's connected or not).
I am using a UIPickerView to display answers to a question. There needs to then be a button to reveal the correct answer if the user cannot work it out. I have tried the below, but the app crashes. How can i autoscroll to the correct answer?
-(void)reveal {
[myPickerView selectRow:0 inComponent:0 animated:YES];
}
EDIT: Yes i am just trying to get it to scroll to the first answer in the above example :)
[ExcerciseController reveal:]: unrecognized selector sent to instance 0x68398f0
2012-10-30 14:57:21.673 English[20786:f803] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ExcerciseController reveal:]: unrecognized selector sent to instance 0x68398f0'
* First throw call stack:
(0x1397022 0x108ccd6 0x1398cbd 0x12fded0 0x12fdcb2 0x1398e99 0x1f214e 0x1f20e6 0x298ade 0x298fa7 0x298266 0x2173c0 0x2175e6 0x1fddc4 0x1f1634 0x21a3ef5 0x136b195 0x12cfff2 0x12ce8da 0x12cdd84 0x12cdc9b 0x21a27d8 0x21a288a 0x1ef626 0x2c5d 0x2b85)
terminate called throwing an exception[Switching to process 20786 thread 0xf803]
Now, that the error/crash message is visible, it turns out that the error is not in how you call the picker's method. It is how you invoke reveal.
You call reveal with some object. Or you call it by passing a selector. However, the current selector that you are calling is reveal: but the methods name is reveal without any parameter. reveal: would require one parameter.
Wherever you call it, make sure that you call reveal and not reveal:
I assume you set the selector either in interface builder or when creating the button programmatically. That is the place where you made the mistake.
Some background:
The error message tells you what you need to know. A method name is called selector in Objective-C at runtime. In some literature you will find the wording of a message (named reveal: in your case) is sent to a receiver named ExcerciseController in your case.
Objective-C is polymorph. That means that reveal (called without any parameters) refers to another method implementation than reveal: (called with one parameter) or even reveal:: (called with three parameters).
myPickerView may not be the instance of UIPickerView as UIPickerView responds to selector - (void)selectRow:(NSInteger)row inComponent:(NSInteger)component animated:(BOOL)animated
Or you have to check how the method reveal is invoked.
please try to post the crash description,Need more blocks of code to answer it :)
However just try the below code
myPickerView.delegate = self;
[myPickerView reloadAllComponents];
[myPickerView selectRow:0 inComponent:0 animated:YES];
I am working on a project in which I perform lazy loading of images. When the imagedownloader downloads the images,it sends the message to its delegate to handle the image. But when its delegate,which is a view controller, gets deallocated from memory,I dont want imagedownloader class to send messages to its delegate as its already dead. I need to know when can i set delegate of imagedownloader to nil?? My target is set to iOS4.0 so i cant use weak references. And i have many instances of imagedownloader stored in a dictionary ready to sent their delegate the completion message . I have to set delegte of all those stored instances to nil.For now i am doing
'
-(void)viewWillDisappear:(BOOL)animated
{
for(imagedownloader *imagedownloaderObj in dict)
{
imagedownloaderObj.delegate = nil;
}
[super viewWillDisAppear:animated]
}
but it crashes in the loop. Please help anyone...and sorry about my bad english but i hope you got it whats my problem..
You have a problem in your code - you are enumerating a dictionary which enumerates its keys, not its objects. Instead you want to do:
for(ImageDownloader *imageDownloader in [imageDownloaderDictionary allValues])
{
if (imageDownloader.delegate == self)
imageDownloader.delegate = nil;
} //note - I've adjusted naming to match Objective-C style conventions. It fits in better with the framework code now.
Also, I'd say to do this in dealloc instead. I don't know that you'll always get a viewWillDisappear: method before deallocating, on earlier version of iOS (including iOS4) you certainly couldn't guarantee that. And furthermore you don't want to waste time downloading the images again if you come back to that view.
Stick with me. I'm visually impaired, have never used this site before, and will probably not post this in precisely the format that you are all used to. I apologize for any unintentional faux pas's herein.
Using Objective-C in an iOS project…
I have a singleton class, set up in what appears to be the usual way for Objective-C. It is, in the main, a series of methods which accept NSString values, interprets them, and return something else. In the code below, I'm simplifying things to the barest minimum, to emphasize the problem I am having.
From the singleton class:
- (NSUInteger) assignControlState:(NSString *)state {
// excerpted for clarity...
return UIControlStateNormal; // an example of what might be returned
}
Now, an instance of another class tries to use this method like so:
- (void) buttonSetup:(UIButton*)button {
[button setTitle:#"something" forState:[[SingletonClass accessToInstance] assignControlState:#"normal"]];
}
This code actually works. HOwever, when the system goes to draw the UI which includes the button whose title was set in this way, an EXC_BAD_ACCESS error occurs.
If the assignControlState method is moved into the same class as the buttonSetup method, no error is generated.
I'm guessing this is something about Apple's memory management that I'm not fully understanding, and how things go in and out of scope, but for the life of me, I can't figure out where I'm going wrong.
HOpe someone can help. Thanks.
The problem is in your accessToInstance method. I'll bet you are under-retaining. The implementation should be more like this:
static SingletonClass *sSingletonClass = nil;
#implementation
+ (id)accessToInstance {
if (sSingletonClass == nil) {
sSingletonClass = [[[self class] alloc] init];
}
return sSingletonClass;
}
#end
Now, if your program is following normal memory management rules, the singleton will stay around. You can check by writing:
- (void)dealloc {
[super dealloc]; // <-- set a breakpoint here.
}
If the debugger ever stops at this breakpoint, you know something in your program has over-released the singleton.
You know that bit you excerpted for clarity? I think you need to show us what it is because there's probably an over release in it somewhere.
Specifically, I think you release an autoreleased object. If you do that and don't use the object again, everything will carry on normally until the autorelease pool gets drained. The autorelease pool gets drained automatically at the end of the event at about the same time as the drawing normally occurs.
That would also explain the delayed crash following the NSLogs.