-1

i'm trying to learn programming, and the language i chose to start is objective c! i'm currently studying from : Programing in Objective-C Fourth edition, and am a bit stuck at the classes chapter.

we have the following code :

#import <Foundation/Foundation.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 {
        Fraction *myFraction;

        myFraction = [Fraction alloc];
        myFraction = [Fraction init];

        [myFraction setDenominator:1];
        [myFraction setNumerator:3];

        NSLog(@"The value of myFraction is :");
        [myFraction print];
    }
    return 0;

}

I copied the code from the book, in hopes to help me understand it better, but for some reason when i try to run i get the following message :

2014-04-25 22:23:28.374 cocoTerminal[1751:303] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[Fraction<0x1000011d8> init]: cannot init a class object.'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff8f5a825c __exceptionPreprocess + 172
    1   libobjc.A.dylib                     0x00007fff86403e75 objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff8f5ab490 +[NSObject(NSObject) dealloc] + 0
    3   cocoTerminal                        0x0000000100000dde main + 110
    4   libdyld.dylib                       0x00007fff8d43a5fd start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

If someone would be so kind to explain what and why is causing the error, to a complete noob i will be forever grateful !

Black Frog
  • 11,595
  • 1
  • 35
  • 66
  • 4
    Either your book is not worth its money, or you did not copy from it correctly. `myFraction = [Fraction alloc]` should be `myFraction = [[Fraction alloc] init]` and that should be shown in every Objective-C introduction. – Martin R Apr 25 '14 at 21:42
  • Thanks for the quick reply Martin. The author does state that we can combine as : myFraction = [[Fraction alloc] init]; , or go further and shorten to : Fraction *myFraction=[[Fraction alloc] init]; however, changing this in my code hasn't changed the error that i am receiving. – user3260511 Apr 25 '14 at 22:02
  • `myFraction = [Fraction init];` should obviously be `myFraction = [myFraction init];`, that's why you're getting the exception about trying to `init` a *class* object, when you should be trying to `init` the `myFraction` object. – Crowman Apr 25 '14 at 22:14

2 Answers2

1

You need to initilise the object after allocating it.

myFraction = [[Fraction alloc] init];

For a good explanation on why you need to do so, check here.

Community
  • 1
  • 1
ZeMoon
  • 20,054
  • 5
  • 57
  • 98
0

This line:

myFraction = [Fraction init];

is what is giving rise to the cannot init a class object exception. It should be:

myFraction = [myFraction init];

You send alloc messages to classes, but init messages to instances of classes. You can't send init to a class object, as the error clearly states. Sending alloc to a class gives you an instance of that class, and that instance is what you should be sending init to.

As others have said, combining the two lines into Fraction * myFraction = [[Fraction alloc] init]; is the more usual way of doing it, but the way you're doing it is not actually wrong, once you send the init message to the correct thing.

Crowman
  • 25,242
  • 5
  • 48
  • 56