Objective C - An object inside an interface

Discussion in 'Mac Programming' started by Torchi12, Oct 2, 2011.

  1. Torchi12 macrumors newbie

    Joined:
    Oct 2, 2011
    #1
    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;
    }
    
    
    
     
  2. admanimal macrumors 68040

    Joined:
    Apr 22, 2005
    #2
    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.
     
  3. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #3
    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
     
  4. Torchi12, Oct 2, 2011
    Last edited by a moderator: Oct 2, 2011

    Torchi12 thread starter macrumors newbie

    Joined:
    Oct 2, 2011
    #4
    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.12
    but you cant
     
  5. chown33, Oct 2, 2011
    Last edited: Oct 2, 2011

    chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #5
    ^^^ 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.
     
  6. GorillaPaws macrumors 6502a

    GorillaPaws

    Joined:
    Oct 26, 2003
    Location:
    Richmond, VA
    #6
    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.
     
  7. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #7
    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.
     

Share This Page