Reputation: 19737
In Objective-c 2.0 why do subclasses need to reference instance variables in parent classes using the self
keyword?
Consider this example:
// a.h
@interface MyClass : NSObject
@property (nonatomic, retain) Object *myObject;
@end
// a.m
@implementation MyClass
@synthesize myObject;
@end
// b.h
@interface AnotherClass : MyClass
@end
// b.m
@implementation AnotherClass
- (void) someMethod {
// error
// Object *obj = myObject;
// works
// Object *obj = self.myObject;
}
@end
Upvotes: 11
Views: 8015
Reputation: 92384
You haven't actually defined a variable, you only defined a property (which implicitly defines a variable that is private). And since property are just method, you need the dot syntax. Note that self.property
is the same as [self property]
.
To fix this, specify a variable. I'll give you an example where the variable has a different name than the property. Most people chose the same name for both but I like to have them differ so I immediately see which one is meant.
// a.h
@interface MyClass : NSObject {
// Instance variables are "protected" by default, except if you
// use @private or @public.
Object *myObjectVar;
}
@property (nonatomic, retain) Object *myObject;
@end
// a.m
@implementation MyClass
@synthesize myObject = myObjectVar;
@end
// b.h
@interface AnotherClass : MyClass
@end
// b.m
@implementation AnotherClass
- (void) someMethod {
// works
Object *obj = myObjectVar;
// works
obj = self.myObject;
// the same as self.myObject
obj = [self myObject];
}
@end
Note the difference when you assign: if you assign to your variable the object is not retained automatically. But it is retained if you use the property:
myObjectVar = someObject; // not retained, old object not released!
self.myObject = someObject; // old object released, new object retained
[self setMyObject:someObject]; // same as the line above
Edit: Mentioned that the synthesized instance variables are private by default, as noted by @Jason Coco. And @NSGod is right that normal instance variables are protected by default rather than public, fixed that.
Upvotes: 13
Reputation: 22948
They don't, provided you actually declare an instance variable in the superclass, rather than rely on the new runtime's ability to synthesize the instance variable (in addition to synthesizing the accessor methods). See The Objective-C Programming Language: Runtime Difference for more info on instance variable synthesis.
For example, to be able to refer to the instance variable directly, you'd need to change the following:
@interface MyClass : NSObject
@property (nonatomic, retain) Object *myObject;
@end
to:
@interface MyClass : NSObject {
// there is an implied @protected directive here
Object *myObject;
}
@property (nonatomic, retain) Object *myObject;
@end
By default, instance variables are @protected
, meaning the class and any subclasses can access the instance variables directly. @protected
ivars differ from @public
ivars in that you can't access them using ->
. @private
ivars can only be accessed by the class that declares them. See The Objective-C Programming Language: The Scope of Instance Variables for more info.
Upvotes: 8