Why if I declare a variable in an @implementation block between the {} brackets, does attempting to access the variable in a subclass yield a compile error?
2 Answers
It depends on where you're placing your instance variables. Modern Objective-C lets you place them in your @interface or @implementation, or not declare them at all with @synthesize and auto-synthesize.
Imagine we have a class A:
A.h
@interface A : NSObject
{
@protected
int i;
}
@end
A.m
#import "A.h"
@implementation A
{
@protected
int j;
}
@end
When we declare a subclass B, we import the header and can see the declaration of i, but since we cannot import the implementation, we cannot know about the declaration of j.
The following code produces one error, on the j line.
#import "A.h"
@interface B : A
@end
@implementation B
- (int)i {return i;}
- (int)j {return j;}
@end
Update/Additional note
In addition to implementing classes in their own files (C.m) you can declare multiple implementations in a single file. In this case, these classes can access @implementation ivars declared in the superclass:
C.h
#import "A.h"
@interface C : A
@end
A.m
#import "A.h"
#import "C.h"
@implementation A
{
@protected
int j;
}
@end
@implementation C
- (int)j {return j;}
@end
2 Comments
Instance variables declared in a class's @implementation section are private by default, and therefore not visible in subclasses. You can use the @protected visibility modifier to change the visibility.
@implementation MyClass
{
int _foo; // Can't be accessed directly in subclass code.
@protected
int _bar; // Can be accessed directly in subclass code.
int _baz; // Can be accessed directly in subclass code.
}
@interfaceor@implementation?