Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Torchi12

macrumors newbie
Original poster
Oct 2, 2011
6
0
I don't understand why you can do r.origin without including it in the @property and @synthesize.

Rectangle.h:
Code:
#import <Foundation/Foundation.h>

@class XYPoint;

@interface Rectangle : NSObject
{
    int width, height;
    XYPoint *origin;
}

@property int width, height;

-(XYPoint*) origin;
-(void) setOrigin:(XYPoint*) pt;
-(int) area;
-(int) perimeter;

-(void) setWH: (int) w:(int) h;
@end


main.m
Code:
#import <Foundation/Foundation.h>
#import "Rectangle.h"

int main (int argc, const char* argv[])
{

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    Rectangle *r = [[Rectangle alloc]init];
    
    XYPoint *p = [[XYPoint alloc]init];
    
    r.orgin = p;
    
    
    
    NSLog(@"Width and height is %d and %d", r.width, r.height);

    [r release];
          
    [pool drain];
    return 0;
}
 
I'm guessing the compiler just translates r.origin into either [r origin] or [r setOrigin:] depending on the context, and as long as they exist it doesn't care if you have declared it as a property or not.

You certainly don't need @synthesize if the getter and setter have been manually defined.
 
I'm guessing the compiler just translates r.origin into either [r origin] or [r setOrigin:] depending on the context, and as long as they exist it doesn't care if you have declared it as a property or not.
Yes.

Objective-C Programming Language : Objects Classes & Messaging : Dot Syntax
Code:
myInstance.value = 10;
printf("myInstance value: %d", myInstance.value);
When used with objects, however, dot syntax acts as “syntactic sugar”—it is transformed by the compiler into an invocation of an accessor method. Dot syntax does not directly get or set an instance variable. The code example above is exactly equivalent to the following:
Code:
[myInstance setValue:10];
printf("myInstance value: %d", [myInstance value]);
((Underline added for emphasis))

http://developer.apple.com/library/...html#//apple_ref/doc/uid/TP30001163-CH11-SW17
 
But the XYPoint *p;
is just like a variable.

In that case, you should be able to do
PHP:
@interface whatever:NSObject
{
int a;
}
@end

and then in main.m do:

PHP:
whatever W = [[whatever alloc]init];

W.a = 12

but you cant
 
Last edited by a moderator:
^^^ Wrong.

Look at your original code:
Code:
-(XYPoint*) [B]origin[/B];
-(void) [B]setOrigin[/B]:(XYPoint*) pt;
These method declarations are the accessors. That's all that's needed for dot syntax to work: accessor methods with a suitable name. You don't need to declare @property or @synthesize.

Read what I quoted from the Objective-C guide. It doesn't say anything at all about instance vars being automatically available as properties. Your whatever class only has an instance variable. It has no properties. It has no accessor methods with a suitable name. Therefore, any attempt to use dot syntax will fail.
 
Last edited:
It is possible to directly access an object's ivars, but you should NEVER do it. Objects are designed to encapsulate their data, and to provide specific designated channels to access these values (accessors and mutator methods). When you're first learning, it's hard to appreciate the value of such a system, because everything seems more cumbersome. Trust me when I say that data encapsulation is critical.

One way to think of data encapsulation is like looking at several stereo components that all get wired together via A/V, HDMI, etc cables. If you think of your Amp as an Objective-C object, it will have many variables exposed to other components, but it may have other variables that are self contained and private to the outside world. I'm not an electrical engineer, so the following example is fictional, but suppose the Amp has a variable that regulates the voltage of an incoming signal from the "DVD-IN" port. Further suppose that it needs to change this based on how strong the incoming signal is, and account for the desired volume output. If you're designing an Amp object you want the inputs/outputs to be "public" but you want the voltage regulator to be "private," since a poorly engineered DVD player that was allowed to manipulate this internal variable could fry a circuit, weaken the signal too much or boost it to the point that it blows the speakers.

Object-oriented programming is designed around the concept of objects managing their internals, and creating a "black box" so that other components in the system don't need to understand how they work, they just have to access things via the designated accessors/mutators, and the object will do the rest of the work.

A major advantage of this is that you can change how the Amp Object's voltage regulation works (maybe because you discovered a bug) and all of the other components will still work fine. Notice how if you have external code accessing this data (from potentially many different components such as a DVD, iPod dock, and an Xbox360, etc. they would all have to change their code too. In a simple example like this, the benefits may seem a bit less clear, but imagine objects that are interacting with dozens of other objects, and every time you made one tweak to the object you had to change your code in dozens of other places (and perhaps that code is written by another team-member, so you could seriously screw things up for him if you make a mistake). Things can and do get quickly out-of-hand without using accessors.

By using the designated interfaces, you can change the internals of how your object handles those inputs/outputs in the future in any way you want as long as you keep the interfaces the same. To the external components, it still looks like the same "sockets" so all code that uses the accessors/mutators will work fine. This happens all of the time with Apple's Frameworks. For example, Apple may change the internals of how NSDate objects work because they found some optimization that makes it faster, but all of the thousands of applications and the millions of lines of code that use NSDate will still work just fine because they're using the designated interfaces. I hope this helps appreciate just how powerful this concept is.

A final point is that accessors and mutators can also do checks to make sure that inputs/outputs are appropriate. Perhaps you don't want to allow others to create a rectangle of negative size, so any attempts at setting a side <= 0 will instead change the side to 1 or some other default value. You do this by changing the logic inside the setter's implementation.
 
But the XYPoint *p;
is just like a variable.

In that case, you should be able to do
@interface whatever:NSObject
{
int a;
}
@end

and then in main.m do:

whatever W = [[whatever alloc]init];

W.a = 12


but you cant

As well you should not be able to. You need to think of an object as a self-contained entity. It may contain ivars that you do not want to expose to callers (senders) — private context that the object needs to keep safe in order to maintain its stable state. An example of this might be something like NSFileHandle, which probably relies on a unix file descriptor to perform its operations: if you were able to just modify that value at will, errant code could easily break the NSFileHandle object by putting in an invalid value. This is the point of Objective-C, that you can easily write safe code by relying on the built-in safety mechanisms of the closed OOP design.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.