Dot Syntax Problem

Discussion in 'Mac Programming' started by Blakeasd, Feb 17, 2011.

  1. Blakeasd macrumors 6502a

    Joined:
    Dec 29, 2009
    #1
    Hello,
    I am having some problems using dot syntax. I am trying to access a property from another class, but it isn't working. Here is a simplified version of my code:
    Code:
    
    @interface ClassA : NSObject{
    
    IBOutlet NSColorWell *myWell;
    }
    @property (nonatomic, retain) IBOutlet NSColorWell *myWell;
    
    I synthesize my property in the ClassA implementation. Now to ClassB's implementation file. I am skipping interface as it is not important

    Code:
    #import "ClassA.h"
    #import "ClassA.m"
    #import ClassB.h"
    @implementation ClassB
    
    -(void)awakeFromNib{
    
     [something:[myWell.color]];
    
    }
    
    (Obviously the something method is made up).
    The thing is, even though I import my other classes I can't access my properties from those other classes.

    What am I doing wrong?
     
  2. lee1210, Feb 17, 2011
    Last edited: Feb 17, 2011

    lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    Where in ClassB is a ClassA defined, set, etc.?

    It would be more like:
    [someObject something: myA.myWell.color];
    -Lee
     
  3. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #3
    Is there supposed to be a @synthesize in there somewhere?
     
  4. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #4
    Wrong. It shows the declaration and type of myWell.

    Or it shows that myWell isn't an ivar declared in ClassB, and then we'd tell you that there's no myWell.

    Defects:
    1. You didn't post the error message. We need to see the actual error message.

    2. If myWell isn't an ivar in ClassB (which we can't tell because of no header), then there isn't any variable named myWell in scope, so there's nothing that myWell.color can refer to.

    3. If there is a myWell variable in scope, then myWell.color will be its color property. But you're then apparently sending it a message by enclosing it in []. Unfortunately, you're not actually saying what message to send, because there's nothing except myWell.color between []. And unless myWell.color is an object, you can't message it.

    4. If something: is a method name, then [something:[myWell.color]] makes no sense as a message-send, because there's no target object that the message is being sent to. This is a similar to defect #3 in that it's a malformed message-send, but the defect is different because it's missing a target where #3 is missing a method-name.


    You need to review basic message-send and property syntax.

    Message-send is always [target message]. The message can be a single method name, or it can be a method with parameters. You can't omit the target, nor can you omit the message.

    Basic property syntax is always target.property. There's no enclosing []'s, because that would be message-send syntax.

    The target in both cases is always an object. You can't message anything but objects, and only objects have properties.
     
  5. Blakeasd thread starter macrumors 6502a

    Joined:
    Dec 29, 2009
    #5
    Thanks lee is didn't know the class name had to be in front of the property in another class.
     
  6. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #6
    You need to have an instance of another class, since you're accessing an instance variable. You can have many instances of the same class. I am not fond of the . syntactic sugar for this. While you're learning you may want to stick to message passes while you are getting used to the language, objects, etc.
    [myObject someMethodWithColor: [[myA myWell] color]];

    This is very clear about who is getting which message, etc. Using chained dots... I know some people love it, but it just doesn't sit right with me.

    -Lee
     
  7. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #7
    What you are doing wrong is 1. Not posting actual code that exhibits the problem. 2. Not posting the actual error message.
     
  8. Blakeasd thread starter macrumors 6502a

    Joined:
    Dec 29, 2009
    #8
    I have come across another problem.
    Even though I added the Class in front of the property I am still getting an error:
    Here is my code that is returning the error:
    Code:
    
    DrawingCanvas.backgroundWell.color
    
    
    Here is the error:
    Property 'backgroundWell' not found on object of type 'Drawing Canvas'

    The drawing canvas is a subclass of NSView(Hence the name Drawing Canvas)
    Here is the IBOutlet in Drawing Canvas.h:

    Code:
    
     IBOutlet NSColorWell *backgroundWell;
    
    
    Here is the Property in Drawing Canvas.h

    Code:
    
    @property (nonatomic, retain) IBOutlet  NSColorWell *backgroundWell;
    
    
    I synthesize in DrawingCanvas.m

    Sorry about not posting enough information...hopefully this will provide some clues as to whats wrong.

    Thanks
     
  9. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #9
    Do you have an object variable named DrawingCanvas at that point? Not a class named DrawingCanvas, an actual variable of that name.

    If you don't have an object variable named DrawingCanvas, then it can't possibly have a backgroundWell property. Properties only apply to objects (instances of classes). Properties do not apply to the class object itself. Properties have the same relationship to objects as instance methods.

    Lee1210 already said this (emphasis added):
    If you don't understand the difference between an instance and a class, you should stop coding and go back and review the fundamentals.

    You should also post the complete actual line of code where the error occurs. All you've posted is an isolated expression, not the complete statement. Copy and paste the entire statement, or even several complete lines, where the error occurs. Apologizing for the lack of information doesn't actually provide any useful information.
     
  10. Blakeasd thread starter macrumors 6502a

    Joined:
    Dec 29, 2009
    #10
    I am going to make my question simpler:
    How do I access properties from other classes?
     
  11. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #11
    You don't. Classes don't have properties.

    Objects (instances of a class) do. You need to instantiate an instance of the class, store a pointer to it, then use . or [] to pass a message to get the property.

    -Lee
     
  12. Blakeasd thread starter macrumors 6502a

    Joined:
    Dec 29, 2009
  13. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #13

    Code:
    //ObjectA.h
    #import <Cocoa/Cocoa.h>
    
    @interface ObjectA : NSObject {
    	int height;
    }
    -(ObjectA *) initWithHeight: (int) newHeight;
    
    @property int height;
    
    @end
    
    //ObjectA.m
    #import "ObjectA.h"
    
    @implementation ObjectA
    
    -(ObjectA *) initWithHeight: (int) newHeight {
    	if(!(self = [super init])) 
    		return nil;
    	[self setHeight: newHeight];
    	return self;
    }
    
    @synthesize height;
    
    @end
    
    //ObjectB.h:
    
    #import <Cocoa/Cocoa.h>
    #import "ObjectA.h"
    
    @interface ObjectB : NSObject {
    	ObjectA *myA;
    }
    -(ObjectB *) initWithA: (ObjectA *) newA;
    -(int) getHeightOfA;
    
    @property (retain) ObjectA *myA;
    
    @end
    
    //ObjectB.m
    #import "ObjectB.h"
    
    @implementation ObjectB
    
    -(ObjectB *) initWithA: (ObjectA *) newA {
    	if(!(self = [super init])) 
    		return nil;
    	[self setMyA: newA];
    	return self;
    }
    
    -(int) getHeightOfA {
    	return [myA height];
    }
    
    @synthesize myA;
    
    @end
    
    //main.m
    #import <Foundation/Foundation.h>
    #import "ObjectA.h"
    #import "ObjectB.h"
    
    int main (int argc, const char * argv[]) {
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
        ObjectA *mainA;
        ObjectB *mainB;
        mainA = [[ObjectA alloc] initWithHeight: 79];
        mainB = [[ObjectB alloc] initWithA: mainA];
        NSLog(@"The height of B's A is: %d",[mainB getHeightOfA]);
    	
        [pool drain];
        return 0;
    }urn 0;
    }
    
    You can divide this into the files in the comments, or stick them all into the main file of a project and comment out the #imports for ObjectA.h and ObjectB.h. I did test this once, but make no warranties about the code. It's for demonstration, it may not be 100% correct.

    -Lee
     
  14. Blakeasd, Feb 18, 2011
    Last edited: Feb 19, 2011

    Blakeasd thread starter macrumors 6502a

    Joined:
    Dec 29, 2009
    #14
    Why do you have to create a setter/getter method if we are using dot syntax?
     

Share This Page