@interface MyObjectiveCmainClass
{
@protected
NSMutableArray* thisStringIsInaccessibleInSwiftSubclasses;//this I can't access in swift subclass
}
@property NSString* thisStringIsAccessibleInSwiftSubclasses;//this I can access in swift subclass
- (void) thisMethodIsAccessibleInSwiftSubclasses;//this too I can access in Swift subclass
@end
class MySwiftSubclass : MyObjectiveCmainClass {
override func thisMethodIsAccessibleInSwiftSubclasses() {
NSLog(self.thisStringIsAccessibleInSwiftSubclasses)
}
}
Any Idea why I can’t access the @protected attribute on my ObjectiveC instance variable?
2
Answers
As Alexander Explained in his answer, this is not "straightforwardly" achievable.
Since I'm not willing to alter the objective C super class, I decided to depend on KVC to achieve what I need.
I'll then create a main swift class and do all the KVC work in it.
Objective C instance variables aren’t accessible to Swift at all,
@protected
or otherwise.In fact, Swift does not expose the concept of instance variables at all, only properties. Properties could be computed or stored, but as far as the API is concerned, they’re just properties.
It might be worth mentioning the motivation there: it’s to allow flexibility in library evolution. A library could liberally change which values it stores versus which it derives through computed properties. E.g. that could be done to allow for more efficient internal representations. But as far as the clients are concerned, a property is a property, not too unlike any other function call. They don’t experience a breaking API change.
If the indirection of those properties becomes a performance issue, you can work around it by marking your types as
@frozen
. The property getters can be inlined into direct ivar accesses, but this exposes your type’s internal layout and limits the changes you can make in the future (unless you decide to a breaking change is OK)