What is the Instance/object in the code? - objective-c

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.

Related

How does the Xcode breakpoint system interact with memory management?

Here's a little experiment:
#interface Model : NSObject
#property (copy) NSString *value;
-(instancetype)initWith:(NSString *)value;
#end
#implementation Model
-(instancetype)initWith:(NSString *)value {
self = [super init];
self.value = value;
return self;
}
#end
#import <Foundation/Foundation.h>
#import "Model.h"
void experiment(Model *m);
int main(int argc, const char * argv[]) {
#autoreleasepool {
// insert code here...
NSLog(#"Hello, World!");
Model *ma = [[Model alloc] initWith:[[NSUUID UUID] UUIDString]];
experiment(ma);
NSLog(#"yyy %#", [ma value]);
}
return 0;
}
void experiment(ModelA *m) {
NSString *testValue = nil;
testValue = [m value];
NSLog(#"xxx %#", testValue);
}
When run, this produces the following:
Hello, World!
xxx 6005A7B0-F71C-4755-B1BF-792D6296B716
yyy 6005A7B0-F71C-4755-B1BF-792D6296B716
Program ended with exit code: 0
But suppose I make this line:
testValue = [m value];
part of a breakpoint:
And this changes everything:
Hello, World!
(__NSCFString *) $0 = 0x000000010071e220 #"1C0DCB39-BFBB-4E67-A041-E6B58615BDFD"
xxx 1C0DCB39-BFBB-4E67-A041-E6B58615BDFD
yyy 1C0DCB39-BFBB-4E67-A041-E6B58615BDFD
*** -[CFString release]: message sent to deallocated instance 0x10071e220
And a crash. I see what's happening--the string is released once we exit the function scope, and the second time when the Model object is destroyed, which is an overrelease. But why doesn't the breakpoint (or more precisely, the lldb expression inside the breakpoint) handle the reference count correctly?

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]));
}
}

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.

Unrecognized selector sent to class

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.

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.