views:

355

answers:

2

Hey,

I'm trying to figure out if I can use dot syntax in objective c in order to access class variables.

For example if I have a class named ClassA of type NSObject.

ClassA has an instance of a class named ClassB also of type NSObject.

And ClassB has a variable named myString of type NSString;

In a view controller that has an instance of ClassA as a variable I'm trying to access "myString" by saying

NSString *aString=classA.classB.myString;

Which gives me this error

 error: accessing unknown 'myString' component of a property

if classB can be accessed with the dot syntax why can't the string variable?

///////////added edit//////////

Sorry for the delay. Also the comment box only allows so many characters so I had to use the anser box instead.

#import <Foundation/Foundation.h>

@class PromoTrackValueObject;
@class PromoMixValueObject;
@class PromoSkinValueObject;
@class EventsValueObject;
@class BuyValueObject;


@interface PromoValueObject : NSObject {
    NSString *promoXMLPath;
    NSString *type;
    NSString *username;
    NSString *entityname;
    NSString *userid;
    NSString *hasavatar;
    NSString *trackbuy_profile;
    NSString *bio;
    NSString *country;
    NSString *url_facebook;
    NSString *url_twitter;
    NSString *url_discog;
    NSString *url_myspace;
    NSString *url_chart;
    NSString *labelname;
    NSString *labelurl;
    NSString *labelimg;
    NSString *agent_name;
    NSString *agent_url;
    NSString *agent_img;
    NSString *promo_date;

    PromoTrackValueObject *promoTrack;
    PromoMixValueObject *promoMix;
    PromoSkinValueObject *promoSkin; // class containing string property in question is in here
    EventsValueObject *events;
    BuyValueObject *buy;



}

@property (nonatomic,copy)NSString *promoXMLPath;
@property (nonatomic,copy)NSString *type;
@property (nonatomic,copy)NSString *username;
@property (nonatomic,copy)NSString *entityname;
@property (nonatomic,copy)NSString *userid;
@property(nonatomic,copy)NSString *hasavatar;
@property (nonatomic,copy)NSString *trackbuy_profile;
@property(nonatomic,copy)NSString *bio;
@property(nonatomic,copy)NSString *country;
@property(nonatomic,copy)NSString *url_facebook;
@property(nonatomic,copy)NSString *url_twitter;
@property(nonatomic,copy)NSString *url_discog;
@property(nonatomic,copy)NSString *url_myspace;
@property(nonatomic,copy)NSString *url_chart;
@property(nonatomic,copy)NSString *labelname;
@property(nonatomic,copy)NSString *labelurl;
@property(nonatomic,copy)NSString *labelimg;
@property(nonatomic,copy)NSString *agent_name;
@property(nonatomic,copy)NSString *agent_url;
@property(nonatomic,copy)NSString *agent_img;
@property(nonatomic,copy)NSString *promo_date;

@property(nonatomic,retain)PromoTrackValueObject *promoTrack;
@property(nonatomic,retain)PromoMixValueObject *promoMix;
@property(nonatomic,retain)PromoSkinValueObject *promoSkin;
@property(nonatomic,retain)EventsValueObject *events;
@property(nonatomic,retain)BuyValueObject *buy;
@end


#import "PromoValueObject.h"
@implementation PromoValueObject
@synthesize promoXMLPath;
@synthesize type;
@synthesize username;
@synthesize entityname;
@synthesize userid;
@synthesize hasavatar;
@synthesize trackbuy_profile;
@synthesize bio;
@synthesize country;
@synthesize url_facebook;
@synthesize url_twitter;
@synthesize url_discog;
@synthesize url_myspace;
@synthesize url_chart;
@synthesize labelname;
@synthesize labelurl;
@synthesize labelimg;
@synthesize agent_name;
@synthesize agent_url;
@synthesize agent_img;
@synthesize promoMix;
@synthesize promoSkin;
@synthesize events;
@synthesize buy;
@synthesize promoTrack;
@synthesize promo_date;

- (void)dealloc {
    [promoTrack release];
    [promoMix release];
    [promoSkin release];
    [events release];
    [buy release];
   [promoXMLPath release];
    [type release];
    [username release];
    [entityname release];
    [userid release];
    [hasavatar release];
    [trackbuy_profile release];
    [bio release];
    [country release];
    [url_facebook release];
    [url_twitter release];
    [url_discog release];
    [url_chart release];
    [labelname release];
    [labelurl release];
    [labelimg release];
    [agent_name release];
    [agent_url release];
    [agent_img release];
    [promo_date release];
    [super dealloc];
}

@end

@interface PromoSkinValueObject : NSObject {

    NSString *promo_skin_url;  // the string I'm after
    NSString *promo_skin_id;

}

@property(nonatomic,retain)NSString *promo_skin_url;
@property(nonatomic,retain)NSString *promo_skin_id;


@end



   #import "PromoSkinValueObject.h"


    @implementation PromoSkinValueObject
    @synthesize promo_skin_url;
    @synthesize promo_skin_id;
    @end

//trying to add dot syntax here

This line of code is in a class which sytesizes promoValueObject

NSString *skin=promoValueObject.promoSkin.promo_skin_url;
A: 

Having an ivar is not enable for dot-syntax to work. You need to make it a property by adding

@property(retain) NSString* myString;

to the @interface, and

@synthesize myString;

to the @implementation.

Basically, the getter dot syntax abc.efg can be translated to [abc efg]. But to access an ivar you use the syntax abc->efg, which is a totally different concept. See “Declared Properties” for detail.

KennyTM
hmmm,I have both @property and @synthesize.I tried the whole -> but I got a pointer error. I guess I should just read the link you posted.
dubbeat
You don't need an @property to access something via the dot syntax.
bbum
@dubbeat: Please show your code.
KennyTM
Using `abc->efg` is generally considered poor form. Please write accessors (or `@synthesize` some with a property).
andyvn22
Hi, I posted the code
dubbeat
it turns out I hadnt imported "class B" in my main UIVIEW .. I assumed I wouldnt need to because it was imported in "class A"dumb ...da dumb da dumb.Thanks for all the feedback!
dubbeat
+4  A: 

The dot syntax is designed to be an exactly precise synonym for method invocations to methods that play the setter/getter role. To use the . [dot] syntax, the type of the object must be exactly specified and the object must implement the appropriate method. Dot syntax is not used to somehow gain direct access to instance variables.

Thus, you say:

And ClassB has a variable named myString of type NSString;

And this is likely the problem. You need to either define methods to access myString or declare a property and @synthesize the methods. Either will work and both are effectively equivalent (save for the details of method synthesis when using atomic).


It appears you are confusing "class" and "instance". Everything in your code points to instances of this and that and you are trying to do something like this.that.something where something is failing?

The problem is that you are using @class to forward declare the class reference. Basically, until the full class definition is seen by the compiler, any expression like Foo * where the compiler has only seen @class Foo; acts like a generic reference to an instance of a class of unspecified type (kind of like, but not quite, id).

You need to #import the files containing the declarations of your classes. Think of it in terms of compiler visibility. When you compile the file that has the dot syntax expression, consider the exact set of declarations the compiler has seen prior to that expression being compiled. If the @interface for the class hasn't been seen, you can't use dot syntax on an instance of that class.

bbum