Unrecognized selector sent to class - objective-c

I'm learning Objective-C and just trying out some sample code. I am getting the following error message:
unrecognized selector sent to class
Here is my code.
Basics.m
#import <Foundation/Foundation.h>
#import "Fraction.h"
int main (int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
Fraction *myFraction;
// Create an instance of a Fraction
myFraction = [Fraction alloc];
myFraction = [Fraction init];
// set Fraction to 1/3
[myFraction setNumerator: 1];
[myFraction setDenominator: 3];
// Display the value using the print method
NSLog(#"The value of myFraction is:");
[myFraction print];
[myFraction release];
[pool drain];
return 0;
}
Fraction.h
#import <Foundation/Foundation.h>
// -- interface section --//
#interface Fraction : NSObject {
int numerator;
int denominator;
}
// public method signatures
-(void) print;
-(void) setNumerator: (int) n;
-(void) setDenominator: (int) d;
#end
Fraction.m
//--implementation section --//
#implementation Fraction
-(void) print
{
NSLog(#"%i/%i",numerator,denominator);
}
-(void) setNumerator: (int) n
{
numerator = n;
}
-(void) setDenominator: (int) d
{
denominator = d;
}
#end

alloc is a class method, but init is an instance method. In your code, the compiler is complaining that it can't find any class method named init, which is accurate. To correct this, you should call init upon the instance you received back from alloc, like so:
myFraction = [Fraction alloc];
myFraction = [myFraction init];
but the most common pattern is to nest the calls like this:
// calls -init on the object returned by +alloc
myFraction = [[Fraction alloc] init];
This also helps you avoid errors that might occur by calling methods on an object that has been allocated, but not yet initialized.

In addition to what has been said regarding the nested alloc / init call, something you may be interested in is description. In your Fraction class implementation, add a method like this:
- (NSString *) description
{
return [NSString stringWithFormat:#"%i/%i", numerator, denominator];
}
Now, you can use it directly in NSLog statements like this:
// set Fraction to 1/3
[myFraction setNumerator: 1];
[myFraction setDenominator: 3];
// Display the value using the print method
NSLog(#"The value of myFraction is: %#", myFraction);

I know this answer was awhile ago so I wanted to give a little update. If you are using alloc/init to initialize you can shorten it to just
[Fraction new]
and that will be equivalent.

Related

No errors but NSLog not outputting

I am busy doing a test program in Xcode. So far I have this code in main.m. I get no errors at all, but the output isnt happening i.e NSLog in the print method.
What could be the problem? I know I must be missing something obvious.
#import <UIKit/UIKit.h>
#import "JTAppDelegate.h"
#interface Fraction: NSObject
-(void) print;
-(void) setNumerator: (int) n;
-(void) setDenominator: (int) d;
#end
#implementation Fraction
{
int numerator;
int denominator;
}
-(void) print
{
NSLog (#"%i/%i", numerator, denominator);
}
-(void) setNumerator:(int)n
{
numerator = n;
}
-(void) setDenominator:(int)d
{
denominator = d;
}
#end
int main (int argc, char * argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([JTAppDelegate class]));
// Create an instance of Fraction and initialise it
Fraction *myFraction = [[Fraction alloc] init];
//Set Fraction to 1/3
[myFraction setNumerator: 1];
[myFraction setDenominator: 3];
//Display the fraction using the print method
[myFraction print];
}
}
your printis after a return, this code is never reached.
Write Print and all code above return statement.
Replace this :-
int main (int argc, char * argv[])
{
#autoreleasepool {
// Create an instance of Fraction and initialise it
Fraction *myFraction = [[Fraction alloc] init];
//Set Fraction to 1/3
[myFraction setNumerator: 1];
[myFraction setDenominator: 3];
//Display the fraction using the print method
[myFraction print];
return UIApplicationMain(argc, argv, nil, NSStringFromClass([JTAppDelegate class]));
}
}

What is the Instance/object in the code?

Could Somebody please describe to me what the instance/object is in the following Code (objective-C). I'm confused because the (-) void before void means that its a method for an instance, but I don't know where the instance/object is.
#import <Foundation/Foundation.h>
//interface section
#interface Fraction: NSObject
- (void) print;
- (void)setNumerator: (int) n;
- (void)setDenominator: (int) d;
#end
//implementation section
#implementation Fraction
{
int numerator;
int denominator;
}
-(void) print;
{
NSLog(#"%i/%i",numerator,denominator);
}
-(void) setNumerator:(int)n
{
numerator = n;
}
-(void)setDenominator:(int)d
{
denominator = d;
}
#end
//program section
int main(int argc, const char * argv[])
{
//this is a program to work with fractions-class version
#autoreleasepool {
Fraction *myFraction;
//create an instance of a fraction
myFraction = [Fraction alloc];
myFraction = [myFraction init];
//set fraction to 1/3
[myFraction setNumerator:1];
[myFraction setDenominator:3];
//display the fraction via print methoD
NSLog(#"the value of myFraction is:");
[myFraction print];
}
return 0;
}
myFraction is the instance of the Fraction class. Instance methods have to be addressed to an instance rather than a class, and as you can see, print, setNumerator, and setDenominator are all addressed to myFraction.

Doesn't work the same code from the book <"Programming Objective-c 4th edition" Stephen Kochan>

Why it says that numerator and denominator in the category MathOps is undeclared variable ?
It is in the Chapter 11 and the Program 11.1
Can't understand why it doesn't work, because it is the same code as in the book without any mistakes.
Please help
Code:
#import <Foundation/Foundation.h>
#import "complex.h"
#import "Fraction.h"
#import "XYPoint.h"
#interface Fraction (MathOps)
-(Fraction *)add:(Fraction *) f;
-(Fraction *)mul:(Fraction *) f;
-(Fraction *)sub:(Fraction *) f;
-(Fraction *)div:(Fraction *) f;
#end
#implementation Fraction (MathOps)
-(Fraction *)add:(Fraction *) f
{
Fraction *result = [[Fraction alloc]init];
result.numerator = (numerator * f.denominator)+(denominator * f.numerator);
// numerator and denominator: Using undeclared variables.
result.denominator = denominator * f.denominator;
}
-(Fraction *)mul:(Fraction *) f
{
Fraction *result = [[Fraction alloc]init];
result.numerator = numerator * f.numerator;
result.denominator = denominator * f.denominator;
// numerator and denominator: Using undeclared variables.
}
-(Fraction *)sub:(Fraction *) f {}
-(Fraction *)div:(Fraction *) f {}
#end
typedef Fraction *FractionObj;
int main (int argc, const char * argv[])
{
#autoreleasepool {
complex *imaginary= [[complex alloc]init];
complex *real = [[complex alloc]init];
complex *results;
[real setReal:1];
[real setImaginary:2];
[real print];
[imaginary setReal:2];
[imaginary setImaginary:1];
[imaginary print];
results = [real add: imaginary];
[results print];
NSLog(#"FRACTIONS!");
Fraction *a = [[Fraction alloc]init];
Fraction *b = [[Fraction alloc]init];
id resultFraction;
[a setTo:20 over:3];
[b setTo:1 over:3];
[b minusSign];
[a minusSign];
id ab = a;
id ba = b;
[ab print: 0];
NSLog(#"-");
[ba print: 0];
NSLog(#"=");
resultFraction = [ab multiplyN: ba];
[resultFraction print: 1];
XYPoint *xy = [[XYPoint alloc]init];
[xy setX:100 andY:110];
[xy print];
NSLog(#"VERIFYING \n \n \n");
Fraction *fraction = [[Fraction alloc]init];
complex *Complex = [[complex alloc]init];
id number = [[complex alloc]init];
if([fraction isMemberOfClass: [complex class]])
NSLog(#"Fraction is member of class complex");
if([Complex isMemberOfClass: [NSObject class]])
NSLog(#"complex is member of class NSObject");
if([Complex isKindOfClass: [NSObject class]])
NSLog(#"complex is kind of class NSObject");
if([fraction isKindOfClass: [Fraction class]])
NSLog(#"Fraction is kind of class Fraction");
if([fraction respondsToSelector: #selector(print)])
NSLog(#"Fraction respond to selector print");
if([Complex respondsToSelector: #selector(print)])
NSLog(#"Complex responds to print");
if([Fraction instancesRespondToSelector: #selector(print)])
NSLog(#"Fraction's instances respond to print");
if([number respondsToSelector: #selector (print)])
NSLog(#"number responds to print");
if([number isKindOfClass: [complex class]])
NSLog(#"number is kind of class complex");
if([[number class] respondsToSelector:#selector (alloc)])
NSLog(#"Number class responds to alloc");
if([a counter]!=1){ NSLog(#"%i times was invoked method multiplyN", a.counter); }
else { NSLog(#"Only %i time was invoked method multiplyN", a.counter);}
typedef enum {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday} Day;
}
return 0;
}
Fraction.h:
#interface Fraction : NSObject
#property int numerator, denominator, counter;
//methods
#end
Fraction.m
#implementation
#synthesize numerator, denominator, counter;
//methods
#end
you might want to check your Fraction class file .h, check if you have a set property of numerator and denominator there.
#property(nonatomic, ...) Type *numerator
#property(nonatomic, ...) Type *denominator
and also in your .m file, there should be
#synthesize numerator, denominator
or , in your xcode, point your mouse to that numerator or denominator while holding Command key then click the variable, xcode will take you to the file where the variable is declared, if its not declared, nothing will happen.
Try adding a self. prefix to your code:
result.numerator = (self.numerator * f.denominator)+(self.denominator * f.numerator);
It looks like you're using numerator and denominator without any previous setup of the variables. You may be confused by the fact that these variables have the same names as other variables, but if they aren't associated with the file they're being called from then your program won't recognize them. Your synthesize statement probably needs to be moved to underneath your #implementation statement. I'm somewhat confused by the fact that the code you're showing contains no declaration of numerator and denominator, and I'm sure that your compiler is too.

objective-c synthesizeing leads to error?

I m pretty new to objective-c, and trying some examples on my own. Here is my sample code
#import <objc/objc.h>
#import <Foundation/Foundation.h>
#interface Test:NSObject
{
int noOfWheels;
int total;
}
#property int noOfWheels;
#property int total;
-(void) print;
#end
#implementation Test
#synthesize noOfWheels, total;
-(void) print
{
NSLog (#" noofWheels is %i, total %i ", noOfWheels, total);
}
#end
int main ( int argc, char ** argv)
{
Test *t = [Test alloc];
t = [t init];
[t setnoOfWheels: 10];
[t settotal: 300];
[t print];
}
and it compiled with no error, but when i run the program i get the following error.
Uncaught exception NSInvalidArgumentException, reason: -[Test setnoOfWheels:]: unrecognized selector sent to instance 0x87aef48
What am i doing wrong in my code ?
By default 1st letter of iVar is capitalized in setter method name. So correct call will be:
[t setNoOfWheels: 10];
[t setnoOfWheels: 10];
should be
[t setNoOfWheels: 10];
or even better, since you're declaring a property:
t.noOfWheels = 10;

ignoring messages in objective C

I have some obj-c code, i plan to send unsupport messages in plugin. However i cant seem to ignore messages. I thought "-(id) forward: (SEL) selector: (marg_list) arglist;" would solve it but it hasnt. How do i have this app run entirely without getting a warning and a termination call?
#import <stdio.h>
#import <objc/Object.h>
//------- #interface section -------
#interface Fraction: Object
{
int numerator;
int denominator;
}
-(void) print;
-(void) setNumerator: (int) n;
-(void) setDenominator: (int) d;
-(id) forward: (SEL) selector: (marg_list) arglist;
#end
//------- #implementation section -------
#implementation Fraction;
-(void) print
{
printf (" %i/%i ", numerator, denominator);
}
-(void) setNumerator: (int) n
{
numerator = n;
}
-(void) setDenominator: (int) d
{
denominator = d;
}
-(id) forward: (SEL) selector: (marg_list) arglist
{
return nil;
}
#end
//------- program section -------
int main (int argc, char *argv[])
{
Fraction *myFraction;
// Create an instance of a Fraction
myFraction = [Fraction alloc];
myFraction = [myFraction init];
// Set fraction to 1/3
[myFraction setNumerator: 1];
[myFraction setDenominator: 3];
// Display the fraction using the print method
printf ("The value of myFraction is:");
[myFraction print];
printf ("\n");
[myFraction someMsg: 99];
[myFraction free];
printf("end");
return 0;
}
Rather than handing this in the plugin, it would be best to do it in the caller. Instead of:
[myFraction someMsg: 99];
you should check if myFraction responds to the someMsg selector:
if ([myFraction respondsToSelector:#selector(someMsg:)]) {
[myFraction someMsg: 99];
}
The -respondsToSelector: method is defined in the NSObject Protocol Reference, so note that your MyFraction object needs to inherit from NSObject, not Object (or else implement the NSObject protocol yourself). Of course, this is really best practice anyway -- directly subclassing the Object class is generally discouraged.