i try to understand initializers in obj-c and i can't - objective-c

I try to understand how to work simple init funcion and I don't know where I have made a mistake. Can somebody assist?
Rectangle.h
#interface Rectangle : NSObject
{
int width;
int height;
}
-(id)initObject;
#end
Rectangle.m
#implementation Rectangle
-(id)initObject{
if (self = [super init]) {
height = 5;
width = 7;
}
return self;
}
#end
And in ViewController.h i import Rectangle.h, declare *rect object and in .m i execute(? run?) initObject.
ViewController.h
#import <UIKit/UIKit.h>
#import "Rectangle.h"
#interface ViewController : UIViewController
{
Rectangle *rect;
}
#end
ViewController.m
-(void)viewDidLoad
{
rect = [[Rectangle alloc] initObject];
NSLog(#"%#", rect);
[super viewDidLoad];
}
initObject return me:
2011-11-21 09:43:02.625 initializers[43693:f803] <Rectangle: 0x6ab1660>

The only problem with your code that I can see is you called your initializer -initObject for no good reason. It's not taking any parameters at all, so you really should just call it -init like every other parameterless initializer in the system.
As for the log output, I imagine your confusion lies in the fact that it says <Rectangle: 0x6ab1660>. This is perfectly normal. The default implementation of -description (the method that returns this output) is the name of the class of the object followed by the object's address. In other words, -[NSObject description] is likely to be implemented something like the following:
- (NSString *)description {
return [NSString stringWithFormat:#"<%#: %p>",
NSStringFromClass([self class]),
self];
}
This means that instance variables of your object are not going to be printed. A number of built-in classes do print their instance variables when logged, but this was implemented specifically for that class and is not a generic mechanism. If you want to verify that your Rectangle object is correct, you could implement -description like so:
- (NSString *)description {
return [NSString stringWithFormat:#"<%#: %p width=%d, height=%d>",
NSStringFromClass([self class]),
self,
width,
height];
}

No error! Since your Rectangle class has no description method, calling NSLog(#"%#", rect); will return the class of the object, followed by its address in memory.
If you want to print width and height of the rectangle you may use something like:
in Rectangle.h
#interface Rectangle : NSObject
{
int width;
int height;
}
-(id)initObject;
#property int width, height;
#end
in Rectangle.m
#implementation Rectangle
#synthesize width, height;
-(id)initObject{
if (self = [super init]) {
height = 5;
width = 7;
}
return self;
}
#end
and then call
NSLog(#"width=%d, height=%d", [rect width], [rect height]);

Related

Objective-C Address of property expression

I need access address of property but have problem. example code is
#interface Rectangle : NSObject
{
SDL_Rect wall;
SDL_Rect ground;
}
#property SDL_Rect wall;
#property SDL_Rect ground;
#end
#implementation Rectangle
#synthesize x;
#synthesize y;
#end
#interface Graphics : NSObject
{
int w;
int h;
}
-(void) drawSurface
#end
#implementation Graphics
-(void) drawSurface
{
Rectangle *rect = [[Rectangle alloc] init];
SDL_BlitSurface(camera, NULL, background, &rect.wall);
}
#end
&rect.x is Address of property expression requested
As the comments suggest, you cannot take the address of a property. A property is really just a promise that the object in question provides accessors for some value. The value itself may or may not even exist in an instance variable. For example, the getter for a property called fullName might generate the required value on the fly by concatenating the values of firstName and lastName properties.
Since you need to pass the address of a SDL_Rect into SDL_BlitSurface(), you could first copy the necessary property into a local variable, and then pass the address of that variable:
Rectangle *rect = [[Rectangle alloc] init];
SDL_Rect wall = rect.wall;
SDL_BlitSurface(camera, NULL, background, &wall);
If you need to preserve the value left in wall after the call to SDL_BlitSurface(), copy it back again after the call:
rect.wall = wall;
I had a similar situation with subclasses needing to access a CGAffineTransform defined in the parent class. The answer came from #orpheist's answer to this question: Get the address of an Objective-c property (which is a C struct). It does involve adding a method to your Rectangle class.
#interface Rectangle : NSObject
{
NSRect wall;
NSRect ground;
}
#property NSRect wall;
#property NSRect ground;
#end
#implementation Rectangle
#synthesize wall = _wall; //x;
#synthesize ground = _ground; //y;
- (const NSRect *) addressOfWall {
return &_wall;
}
- (const NSRect *) addressOfGround {
return &_ground;
}
+(instancetype)standardRectangle
{
Rectangle *newInstance = [[self alloc] init];
newInstance.wall = NSMakeRect(0,0, 300, 100);
newInstance.ground = NSMakeRect(0 ,0, 300, 450);
return newInstance;
}
#end
Now you can use, for instance, addressOfWall thus:
- (void)testWall
{
Rectangle *rect = [Rectangle standardRectangle];
XCTAssertEqual(100, [rect addressOfWall]->size.height);
}
Address of property expression requested that means:
#preperty (nonatomic,copy) NSString *name;
if you want to get the address of self.name. You cannot write the code like this:
NSLog (#"%p",&(self.name));
Because in fact,self.name is getter method, like this:
- (NSString *)name {
return _name;
}
so you cannot get address of method.

polymorphism methods in ios

I have a doubt in implementing oops concept in objective-c.Is Pholyorphism possible in objective-c. How to implement polymorphism in objective-c.please explain with example?
Every method, including class methods, is dynamic in Objective-C.
One very basic approach would be:
Declare the base interface:
#interface MONConstantColor : NSObject
- (UIColor *)color;
#end
Define the base implementation:
#implementation MONConstantColor
- (UIColor *)color { return /* ...do/ret something appropriate */; }
#end
Then create some variations:
#interface MONRedColor : MONConstantColor
#end
#implementation MONRedColor
- (UIColor *)color { return [UIColor redColor]; }
#end
#interface MONYellowColor : MONConstantColor
#end
#implementation MONYellowColor
- (UIColor *)color { return [UIColor yellowColor]; }
#end
- (HomeWorkResult *)homeWorkResultFromHomeWorkTask:(HomeWorkTask *)task
{
if (!self.lazy) {
return [self HW_performHomeWorkTask:task];
}
StackOverflowPost *post = [StackOverflow postHomeWorkTask:task];
for (id user in post.responders) {
// Here is the pholyorphism[sic].
// First, test to see if a stack overflow user is able to do home work tasks.
if ([user respondsToSelector:#selector(homeWorkResultFromHomeWorkTask:)]) {
// Next, have the user do the home work task.
HomeWorkResult *result = [user homeWorkResultFromHomeWorkTask:task];
// If there is a result, return that result.
if (result) {
return result;
}
}
}
// Finally, if no stack overflow user does home work tasks or if there was no
// result perform the task yourself.
return [self HW_performHomeWorkTask:task];
}
The word polymorphism means having many forms
Objective-C polymorphism means that a call to a member function will cause a different function to be executed depending on the type of object that invokes the function.
Consider the example, we have a class Shape that provides the basic interface for all the shapes. Square and Rectangle are derived from the base class Shape.
We have the method printArea that is going to show about the OOP feature polymorphism.
#import <Foundation/Foundation.h>
#interface Shape : NSObject
{
CGFloat area;
}
- (void)printArea;
- (void)calculateArea;
#end
#implementation Shape
- (void)printArea{
NSLog(#"The area is %f", area);
}
- (void)calculateArea{
}
#end
#interface Square : Shape
{
CGFloat length;
}
- (id)initWithSide:(CGFloat)side;
- (void)calculateArea;
#end
#implementation Square
- (id)initWithSide:(CGFloat)side{
length = side;
return self;
}
- (void)calculateArea{
area = length * length;
}
- (void)printArea{
NSLog(#"The area of square is %f", area);
}
#end
#interface Rectangle : Shape
{
CGFloat length;
CGFloat breadth;
}
- (id)initWithLength:(CGFloat)rLength andBreadth:(CGFloat)rBreadth;
#end
#implementation Rectangle
- (id)initWithLength:(CGFloat)rLength andBreadth:(CGFloat)rBreadth{
length = rLength;
breadth = rBreadth;
return self;
}
- (void)calculateArea{
area = length * breadth;
}
#end
int main(int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Shape *square = [[Square alloc]initWithSide:10.0];
[square calculateArea];
[square printArea];
Shape *rect = [[Rectangle alloc]
initWithLength:10.0 andBreadth:5.0];
[rect calculateArea];
[rect printArea];
[pool drain];
return 0;
}
use this link as refernce
http://www.tutorialspoint.com/objective_c/objective_c_polymorphism.htm

imageitem class define

i need to build an application that define an array that should be made of image items.
every image iten has an image, a name and a photographer name.
i build my image item class and i want you to check if my define is correct and good(i just start to learn objective c).
i want you to emphasize on the set's methods.
here is the photoitem.h:
#import <Foundation/Foundation.h>
#interface photoItem : NSObject
{
UIImage *imageView;
NSString *photoNameLabel;
NSString *photographerNameLabel;
UIButton *viewPhoto;
}
#property(readonly) NSString *name;
#property(readonly) NSString *nameOfPhotographer;
#property(readonly) UIImage *imageItem;
-(id)makePhotoItemWIthPhoto:(UIImage*)image name:(NSString*)photoName photographer: (NSString*)photographerName;
#end
here is my photoitem.m:
#import "photoItem.h"
#implementation photoItem
#synthesize name;
#synthesize nameOfPhotographer;
#synthesize imageItem;
-(id)makePhotoItemWIthPhoto:(UIImage*)image name:(NSString*)photoName photographer:(NSString*)photographerName
{
[self setName:photoName];
[self setNameOfPhotographer:photographerName];
[self setImageItem:image];
return self;
}
-(void) setName:(NSString *)name
{
photoNameLabel = name;
}
-(void) setNameOfPhotographer:(NSString *)nameOfPhotographer
{
photographerNameLabel = nameOfPhotographer;
}
-(void)setImageItem:(UIImage *)imageItem
{
imageView = imageItem;
}
#end
i hope you could fix my errors(if there are some).
thanks.
Two problems come to mind:
1) -(id)makePhotoItemWIthPhoto:name:photographer: might be better as -(id)initWithPhoto:name:photographer:. Otherwise the caller needs to alloc and init an object first so that self is valid, then call your method. At that point, the return of self doesn't make sense.
Example:
-(idinitWithPhoto:(UIImage*)image name:(NSString*)photoName photographer:(NSString*)photographerName {
self = [super init];
if (self) {
[self setName:photoName];
[self setNameOfPhotographer:photographerName];
[self setImageItem:image];
}
return self;
}
2) The three readonly properties don't seem to have any purpose since they have no connection to the variables that you initialize in the makePhotoItemWIthPhoto: method.

Help with a method that returns a value by running another object's method

I have a Class that runs the following method (a getter):
// the interface
#interface MyClass : NSObject{
NSNumber *myFloatValue;
}
- (double)myFloatValue;
- (void)setMyFloatValue:(float)floatInput;
#end
// the implementation
#implementation
- (MyClass *)init{
if (self = [super init]){
myFloatValue = [[NSNumber alloc] initWithFloat:3.14];
}
return self;
}
// I understand that NSNumbers are non-mutable objects and can't be
// used like variables.
// Hence I decided to make make the getter's implementation like this
- (double)myFloatValue{
return [myFloatValue floatValue];
}
- (void)setMyFloatValue:(float)floatInput{
if ([self myFloatValue] != floatInput){
[myFloatValue release];
myFloatValue = [[NSNumber alloc] initWithFloat:floatInput;
}
#end
When I mouse over the myFloatValue object during debugging, it does not contain a value. Instead it says: "out of scope".
I would like to be able to make this work without using #property, using something other than NSNumbers, or other major changes since I just want to understand the concepts first. Most importantly, I would like to know what mistake I've apparently made.
I can see a couple of mistakes:
The line #implementation should read #implementation MyClass
The function setMyFloatValue is missing a closing ] and } —it should read:
- (void)setMyFloatValue:(float)floatInput{
if ([self myFloatValue] != floatInput){
[myFloatValue release];
myFloatValue = [[NSNumber alloc] initWithFloat:floatInput];
}
}
I've just tested it in Xcode and it works for me with these changes.
Why not just set property in interface and synthesize accessors in implementation?
#interface MyClass : NSObject {
float *myFloat
}
#property (assign) float myFloat;
#end
#implementation MyClass
#synthesize myFloat;
#end

Objective-C getter/ setter

I'm trying to work my way through an Objective-C tutorial. In the book there is this example:
#interface
{
int width;
int height;
XYPoint *origin;
}
#property int width, height;
I thought, "hey there's no getter/setter for the XYPoint object. The code does work though." Now i'm going maybe to answer my own question :).
I thinks its because "origin" is a pointer already, and whats happening under the hood with "width" and "height", is that there is going te be created a pointer to them..
Am i right, or am i talking BS :) ??
I just dont get it. here's main:
#import "Rectangle.h"
#import "XYPoint.h"
int main (int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Rectangle *myRect = [[Rectangle alloc] init];
XYPoint *myPoint = [[XYPoint alloc] init];
[myPoint setX: 100 andY: 200];
[myRect setWidth: 5 andHeight: 8];
myRect.origin = myPoint;
NSLog (#"Rectangle w = %i, h = %i",
myRect.width, myRect.height);
NSLog (#"Origin at (%i, %i)",
myRect.origin.x, myRect.origin.y);
NSLog (#"Area = %i, Perimeter = %i",
[myRect area], [myRect perimeter]);
[myRect release];
[myPoint release];
[pool drain];
return 0;
}
And here's the Rectangle object:
#import "Rectangle.h"
#import "XYPoint.h"
#implementation Rectangle
#synthesize width, height;
-(void) setWidth: (int) w andHeight: (int) h
{
width = w;
height = h;
}
- (void) setOrigin: (XYPoint *) pt
{
origin = pt;
}
-(int) area
{
return width * height;
}
-(int) perimeter
{
return (width + height) * 2;
}
-(XYPoint *) origin
{
return origin;
}
#end
What i dont understand is this line in main: myRect.origin = myPoint; I did not make a setter for it..
BTW thanks for your fast reply's
What i dont understand is this line in main: myRect.origin = myPoint; I did not make a setter for it..
There is both a getter and a setter (collectively referred to as accessors) created for origin in the Rectangle class. If you have a look in the implementation for Rectangle, this is the getter:
-(XYPoint *) origin
{
return origin;
}
and this is the setter:
- (void) setOrigin: (XYPoint *) pt
{
origin = pt;
}
And as of Objective-C 2.0 calling:
myRect.origin = myPoint;
is equivalent to:
[myRect setOrigin:myPoint];
Declaring getters and setters using #property (and then implementing them using #synthesize) is only one way of declaring and creating accessors, and is there for a convenience if you have lots of properties to declare in the class interface. As Schildmeijer said, #property int width is equivalent to declaring two methods:
- (int)width;
- (void)setWidth:(int)newWidth;
Due to the dynamically-bound nature of Objective-C method calls, you don't even have to declare the getter and setter methods in the interface, although it is generally best practice to do so if you are advertising them as publicly available to other classes.
You can think of a property declaration as being equivalent to declaring two accessor methods. Thus
#property int width;
is equivalent to:
- (int)width;
- (void)setWidth:(int)newWidth;
//Rectangle.h
#import <Foundation/Foundation.h>
#interface Rectangle : NSObject
#property int Width;
#property int Height;
-(int)Area;
#end
//Rectangle.m
#import "Rectangle.h"
#implementation Rectangle
#synthesize Width;/*Will create value Width , Setter called"setWidth" and Getter called "Width"*/
#synthesize Height;/*Will create value Height , Setter called"setHeight" and Getter called "Height"*/
-(int)Area
{
return Width*Height;
}
#end
// main.m
#import <Cocoa/Cocoa.h>
#import "Rectangle.h"
int main(int argc, const char * argv[])
{
Rectangle *myRectangle = [Rectangle new];
myRectangle.Width=3;
myRectangle.Height=5;
printf("Area = %d\n",[myRectangle Area]);
//Or
[myRectangle setWidth:5];
[myRectangle setHeight:6];
printf("Area = %d\n",[myRectangle Area]);
}
If you want to make Getter only or rename getter and setter
• readonly
• getter = newGetterName
• setter = new SetterName
example
//Rectangle.h
#import <Foundation/Foundation.h>
#interface Rectangle : NSObject
#property (getter = getWidth) int Width;
#property (readonly) int Height;
#end
You don't say what code is working, or what your expectations are for "working".
The above interface will create simple accessor methods for width and height that can be called from other objects as [object setWidth:1]; or object.width = 1; - these two are analogous.
Origin is some other object type and is a pointer, yes. But you would still want to declare a property for it to generate accessor methods.
Getters and setters are mostly useful if you need to access an instance variable from another class or you're using bindings to get/set them. So my guess would be that you need this functionality for the width and height but not for the origin. Note that the getters/setters do not make pointers out of the integers as you stated might be the reason. Ints are ints and getters/setters do not change that.